diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index fdda3c0346..2c539c4429 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -42,6 +42,9 @@ jobs: sudo apt install libmpfr-dev #required by rmpfr packages sudo apt install libglpk-dev #required by igraph packages sudo apt install jags + sudo apt install libminizip-dev # required by freexl + git clone https://github.com/jasp-stats/freexl.git + cd freexl && ./configure && make && sudo make install - name: Install boost uses: MarkusJx/install-boost@v2.4.4 diff --git a/.gitmodules b/.gitmodules index ef714265a4..1c8979da20 100644 --- a/.gitmodules +++ b/.gitmodules @@ -150,3 +150,11 @@ path = Common/jaspColumnEncoder url = https://github.com/jasp-stats/jaspColumnEncoder branch = master +[submodule "Engine/jaspModuleInstaller"] + path = Engine/jaspModuleInstaller + url = https://github.com/jasp-stats/jaspModuleInstaller.git + branch = master +[submodule "Modules/jaspBFF"] + path = Modules/jaspBFF + url = https://github.com/jasp-stats/jaspBFF + branch = master diff --git a/Common/utilenums.h b/Common/utilenums.h index 510717923f..a51fecf8c5 100644 --- a/Common/utilenums.h +++ b/Common/utilenums.h @@ -2,7 +2,7 @@ #define UTILENUMS_H #include "enumutilities.h" -DECLARE_ENUM(FileTypeBase, jasp = 0, html, csv, txt, tsv, sav, zsav, ods, pdf, sas7bdat, sas7bcat, por, xpt, dta, database, empty, unknown ); +DECLARE_ENUM(FileTypeBase, jasp = 0, html, csv, txt, tsv, sav, zsav, ods, xls, xlsx, pdf, sas7bdat, sas7bcat, por, xpt, dta, database, empty, unknown ); //const QStringList Database::dbTypes() const should be updated if DbType is changed. DECLARE_ENUM(DbType, NOTCHOSEN, QDB2, /*QIBASE,*/ QMYSQL, QOCI, QODBC, QPSQL, QSQLITE /*, QSQLITE2, QTDS*/ ); diff --git a/CommonData/column.cpp b/CommonData/column.cpp index 4bd1d1f89a..46e79e0519 100644 --- a/CommonData/column.cpp +++ b/CommonData/column.cpp @@ -24,7 +24,10 @@ Column::Column(DataSet * data, int id) _emptyValues( new EmptyValues(data->emptyValues())), _doubleDummy( new Label(this)), _autoSortByValue( _autoSortByValuesByDefault) -{} +{ + if(_id != -1) + db().columnSetAutoSort(_id, _autoSortByValue); //Store autosort in db +} Column::~Column() { @@ -82,7 +85,7 @@ void Column::dbDelete(bool cleanUpRest) { assert(_id != -1); - labelsClear(); + labelsClear(false); db().columnDelete(_id, cleanUpRest); _id = -1; @@ -649,13 +652,14 @@ void Column::_sortLabelsByOrder() std::sort(_labels.begin(), _labels.end(), [](const Label * l, const Label * r) { return l->order() < r->order(); }); } -void Column::labelsClear() +void Column::labelsClear(bool doIncRevision) { db().labelsClear(_id); _labels.clear(); _labelByIntsIdMap.clear(); - incRevision(false); + if(doIncRevision) + incRevision(false); } void Column::beginBatchedLabelsDB() diff --git a/CommonData/column.h b/CommonData/column.h index 10b8fc8202..eb204e3f07 100644 --- a/CommonData/column.h +++ b/CommonData/column.h @@ -109,7 +109,7 @@ class Column : public DataSetBaseNode void upgradeSetDoubleLabelsInInts(); ///< Used by upgrade 0.18.* -> 0.19 void upgradeExtractDoublesIntsFromLabels(); ///< Used by upgrade 0.18.* -> 0.19 - void labelsClear(); + void labelsClear(bool doIncRevision=true); int labelsAdd( int display); int labelsAdd( const std::string & display); int labelsAdd( const std::string & display, const std::string & description, const Json::Value & originalValue); diff --git a/CommonData/databaseinterface.cpp b/CommonData/databaseinterface.cpp index 7e9415c1bd..abbe007d95 100644 --- a/CommonData/databaseinterface.cpp +++ b/CommonData/databaseinterface.cpp @@ -75,7 +75,7 @@ int DatabaseInterface::dataSetInsert(const std::string & dataFilePath, long data transactionWriteBegin(); int id = runStatementsId("INSERT INTO DataSets (dataFilePath, dataFileTimestamp, description, databaseJson, emptyValuesJson, dataFileSynch) VALUES (?, ?, ?, ?, ?, ?) RETURNING id;", prepare); - runStatements("CREATE TABLE " + dataSetName(id) + " (rowNumber INTEGER PRIMARY KEY);"); + runStatements("CREATE TABLE " + dataSetName(id) + " (rowNumber INTEGER PRIMARY KEY);"); // Can be overwritten through dataSetCreateTable transactionWriteEnd(); return id; @@ -183,6 +183,7 @@ void DatabaseInterface::filterDelete(int filterIndex) if(dataSetId != -1) runStatements("ALTER TABLE " + dataSetName(dataSetId) + " DROP COLUMN " + filterName(filterIndex) + ";"); + runStatements("DELETE FROM Filters WHERE id = " + std::to_string(filterIndex) + ";"); transactionWriteEnd(); @@ -391,7 +392,7 @@ void DatabaseInterface::filterWrite(int filterIndex, const std::vector & v transactionWriteEnd(); } -int DatabaseInterface::columnInsert(int dataSetId, int index, const std::string & name, columnType colType) +int DatabaseInterface::columnInsert(int dataSetId, int index, const std::string & name, columnType colType, bool alterTable) { JASPTIMER_SCOPE(DatabaseInterface::columnInsert); transactionWriteBegin(); @@ -419,19 +420,38 @@ int DatabaseInterface::columnInsert(int dataSetId, int index, const std::string Log::log() << "Inserting column failed!" << std::endl; #endif - //Add a scalar and ordinal/nominal column to DataSet_# for the column - const std::string alterDatasetPrefix = "ALTER TABLE " + dataSetName(dataSetId); - const std::string addColumnFragment = " ADD " + columnBaseName(columnId); - - runStatements(alterDatasetPrefix + addColumnFragment + "_DBL REAL NULL;"); - runStatements(alterDatasetPrefix + addColumnFragment + "_INT INT NULL;"); - + + if(alterTable) //If not then via dataSetCreateTable + { + //Add a scalar and ordinal/nominal column to DataSet_# for the column + const std::string alterDatasetPrefix = "ALTER TABLE " + dataSetName(dataSetId); + const std::string addColumnFragment = " ADD " + columnBaseName(columnId); + + runStatements(alterDatasetPrefix + addColumnFragment + "_DBL REAL NULL;"); + runStatements(alterDatasetPrefix + addColumnFragment + "_INT INT NULL;"); + } + //The labels will be added separately later transactionWriteEnd(); return columnId; } +void DatabaseInterface::dataSetCreateTable(DataSet * dataSet) +{ + runStatements("DROP TABLE " + dataSetName(dataSet->id()) + ";"); + + std::stringstream statements; + statements << "CREATE TABLE " + dataSetName(dataSet->id()) + " (rowNumber INTEGER PRIMARY KEY, "+ filterName(dataSet->filter()->id()) + " INT NOT NULL DEFAULT 1"; + + for(Column * column : dataSet->columns()) + statements << ", " << columnBaseName(column->id()) << "_DBL REAL NULL, " << columnBaseName(column->id()) << "_INT INT NULL"; + + statements << ");"; + + runStatements(statements.str()); +} + int DatabaseInterface::columnGetDataSetId(int columnId) { JASPTIMER_SCOPE(DatabaseInterface::columnGetDataSetId); @@ -1438,19 +1458,19 @@ void DatabaseInterface::_runStatements(const std::string & statements, bindParam } while(remain > 1 && (ret == SQLITE_OK && ret != SQLITE_DONE)); + const int maxLenStatementError = 200; + std::string shortStatements = statements.size() <= maxLenStatementError ? statements : statements.substr(0, maxLenStatementError); + if(ret == SQLITE_ERROR) { - std::string errorMsg = "Running ```\n"+statements+"\n``` failed because of: `" + sqlite3_errmsg(_db); - Log::log() << errorMsg << std::endl; - - throw std::runtime_error(errorMsg); + Log::log() << "Running ```\n"+statements +"\n``` failed because of: `" + sqlite3_errmsg(_db) << std::endl; + throw std::runtime_error( "Running ```\n"+shortStatements +"\n``` failed because of: `" + sqlite3_errmsg(_db)); } if(ret == SQLITE_READONLY) { - std::string errorMsg = "Running ```\n"+statements+"\n``` failed because the database is readonly..."; - Log::log() << errorMsg << std::endl; - throw std::runtime_error(errorMsg); + Log::log() << "Running ```\n"+statements +"\n``` failed because the database is readonly..." << std::endl; + throw std::runtime_error( "Running ```\n"+shortStatements +"\n``` failed because the database is readonly..."); } } @@ -1569,8 +1589,7 @@ void DatabaseInterface::create() } else Log::log() << "Opened internal sqlite database for creation at '" << dbFile() << "'." << std::endl; - - + transactionWriteBegin(); runStatements(_dbConstructionSql); transactionWriteEnd(); @@ -1593,6 +1612,7 @@ void DatabaseInterface::load() } else Log::log() << "Opened internal sqlite database for loading at '" << dbFile() << "'." << std::endl; + } void DatabaseInterface::close() @@ -1662,3 +1682,4 @@ void DatabaseInterface::transactionReadEnd() runStatements("COMMIT"); } + diff --git a/CommonData/databaseinterface.h b/CommonData/databaseinterface.h index b4fdfad644..d556ab7b41 100644 --- a/CommonData/databaseinterface.h +++ b/CommonData/databaseinterface.h @@ -87,6 +87,7 @@ class DatabaseInterface int dataSetGetRevision( int dataSetId); int dataSetGetFilter( int dataSetId); void dataSetInsertEmptyRow( int dataSetId, size_t row); + void dataSetCreateTable( DataSet * dataSet); ///< Assumes you are importing fresh data and havent created any DataSet_? table yet void dataSetBatchedValuesUpdate(DataSet * data, std::vector columns, std::function progressCallback = [](float){}); void dataSetBatchedValuesUpdate(DataSet * data, std::function progressCallback = [](float){}); @@ -109,7 +110,7 @@ class DatabaseInterface //Columns & Data/Values //Index stuff: - int columnInsert( int dataSetId, int index = -1, const std::string & name = "", columnType colType = columnType::unknown); ///< Insert a row into Columns and create the corresponding columns in DataSet_? Also makes sure the indices are correct + int columnInsert( int dataSetId, int index = -1, const std::string & name = "", columnType colType = columnType::unknown, bool alterTable=true); ///< Insert a row into Columns and create the corresponding columns in DataSet_? Also makes sure the indices are correct int columnLastFreeIndex( int dataSetId); void columnIndexIncrements( int dataSetId, int index); ///< If index already is in use that column and all after are incremented by 1 void columnIndexDecrements( int dataSetId, int index); ///< Indices bigger than index are decremented, assumption is that the previous one using it has been removed already @@ -157,7 +158,7 @@ class DatabaseInterface void transactionWriteEnd(bool rollback = false); ///< runs COMMIT or ROLLBACK based on rollback and ends the transaction. Tracks whether nested and only does BEGIN+COMMIT at lowest depth void transactionReadBegin(); ///< runs BEGIN DEFERRED and waits for sqlite to not be busy anymore if some other process is writing Tracks whether nested and only does BEGIN+COMMIT at lowest depth void transactionReadEnd(); ///< runs COMMIT and ends the transaction. Tracks whether nested and only does BEGIN+COMMIT at lowest depth - + private: void _doubleTroubleBinder(sqlite3_stmt *stmt, int param, double dbl); ///< Needed to work around the lack of support for NAN, INF and NEG_INF in sqlite, converts those to string to make use of sqlite flexibility double _doubleTroubleReader(sqlite3_stmt *stmt, int colI); ///< The reading counterpart to _doubleTroubleBinder to convert string representations of NAN, INF and NEG_INF back to double diff --git a/CommonData/dataset.cpp b/CommonData/dataset.cpp index 5dde9073e4..59f82d2301 100644 --- a/CommonData/dataset.cpp +++ b/CommonData/dataset.cpp @@ -59,6 +59,7 @@ void DataSet::dbDelete() _dataSetID = -1; + db().transactionWriteEnd(); } @@ -171,12 +172,12 @@ void DataSet::removeColumn(const std::string & name) } } -void DataSet::insertColumn(size_t index) +void DataSet::insertColumn(size_t index, bool alterDataSetTable) { assert(_dataSetID > 0); - Column * newColumn = new Column(this, db().columnInsert(_dataSetID, index)); + Column * newColumn = new Column(this, db().columnInsert(_dataSetID, index, "", columnType::unknown, alterDataSetTable)); _columns.insert(_columns.begin()+index, newColumn); @@ -382,18 +383,24 @@ void DataSet::setColumnCount(size_t colCount) db().transactionWriteBegin(); int curCount = columns().size(); + + bool alterTableAfterwards = curCount == 0 && colCount > 0; if(colCount > curCount) for(size_t i=curCount; i=colCount; i--) removeColumn(i); + incRevision(); db().transactionWriteEnd(); + + if(alterTableAfterwards) + db().dataSetCreateTable(this); } void DataSet::setRowCount(size_t rowCount) diff --git a/CommonData/dataset.h b/CommonData/dataset.h index 62f5bacffc..04d59b3252 100644 --- a/CommonData/dataset.h +++ b/CommonData/dataset.h @@ -40,11 +40,11 @@ class DataSet : public DataSetBaseNode void beginBatchedToDB(); void endBatchedToDB(std::function progressCallback = [](float){}, Columns columns={}); void endBatchedToDB(Columns columns) { endBatchedToDB([](float){}, columns); } - + void removeColumn( const std::string & name ); void removeColumn( size_t index ); void removeColumnById( size_t id ); - void insertColumn( size_t index ); + void insertColumn( size_t index, bool alterDataSetTable = true); Column * newColumn( const std::string & name); int getColumnIndex( const std::string & name ) const; int columnIndex( const Column * col ) const; diff --git a/Desktop/CMakeLists.txt b/Desktop/CMakeLists.txt index 2cb64324fd..79e8c4e39b 100644 --- a/Desktop/CMakeLists.txt +++ b/Desktop/CMakeLists.txt @@ -42,7 +42,7 @@ qt_add_executable( ${BUNDLE_RESOURCES} $<$:${CMAKE_CURRENT_LIST_DIR}/icon.rc> $<$:${_R_Framework}> - $<$:${CMAKE_SOURCE_DIR}/Desktop/JASP.exe.manifest> + $<$:${CMAKE_SOURCE_DIR}/Desktop/JASP.exe.manifest> ) set( @@ -105,6 +105,7 @@ target_include_directories( $<$:/app/include/QtCore5Compat> $<$:/app/include/QtWebEngineQuick> $<$:/app/include/QtWebEngineCore> + ${LIBFREEXL_INCLUDE_DIRS} ) target_link_libraries( @@ -145,6 +146,9 @@ target_link_libraries( Iconv::Iconv OpenSSL::SSL OpenSSL::Crypto + # FreeXL + ${LIBFREEXL_LIBRARIES} + $<$>:freexl::freexl> # ReadStat ----------------------------------- ${LIBREADSTAT_LIBRARIES} # MinGW's ReadStat diff --git a/Desktop/components/JASP/Widgets/ComputeColumnWindow.qml b/Desktop/components/JASP/Widgets/ComputeColumnWindow.qml index 5ab87cced6..4f32ffe940 100644 --- a/Desktop/components/JASP/Widgets/ComputeColumnWindow.qml +++ b/Desktop/components/JASP/Widgets/ComputeColumnWindow.qml @@ -2,6 +2,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.3 import JASP.Controls 1.0 as JaspControls +import JASP import "FilterConstructor" @@ -103,6 +104,12 @@ FocusScope TextArea { id: computeColumnEdit + + RSyntaxHighlighterQuick + { + textDocument: computeColumnEdit.textDocument + } + anchors.top: parent.top anchors.left: parent.left diff --git a/Desktop/components/JASP/Widgets/DataPanel.qml b/Desktop/components/JASP/Widgets/DataPanel.qml index fbb7b53f03..b48f1b6d71 100644 --- a/Desktop/components/JASP/Widgets/DataPanel.qml +++ b/Desktop/components/JASP/Widgets/DataPanel.qml @@ -22,7 +22,7 @@ Rectangle id: filterWindow objectName: "filterWindow" SplitView.minimumHeight: desiredMinimumHeight - SplitView.preferredHeight: rootDataset.height * 0.25 + SplitView.preferredHeight: desiredHeight SplitView.maximumHeight: rootDataset.height * 0.8 } diff --git a/Desktop/components/JASP/Widgets/FileMenu/PrefsUI.qml b/Desktop/components/JASP/Widgets/FileMenu/PrefsUI.qml index dc5492eb02..09247d689a 100644 --- a/Desktop/components/JASP/Widgets/FileMenu/PrefsUI.qml +++ b/Desktop/components/JASP/Widgets/FileMenu/PrefsUI.qml @@ -50,19 +50,44 @@ ScrollView { id: fontGroup title: qsTr("Fonts") - - property real maxText: Math.max(Math.max(interfaceTxt.implicitWidth, codeTxt.implicitWidth), Math.max(resultTxt.implicitWidth, languageTxt.implicitWidth)); - Row + Item { - spacing: 3 * preferencesModel.uiScale - width: parent.width + visible: false; + // If the defaultInterfaceFont etc does not exist on the machine, then the default font of the machine is used. + // These (invisible) Text items are just to ask what will be the real font used. + + Text + { + + id: defaultInterfaceFont + font.family: preferencesModel.defaultInterfaceFont + text: fontInfo.family + } - Text { id: interfaceTxt; width: fontGroup.maxText; text: qsTr("Interface:") } + Text + { + id: defaultRCodeFont + text: fontInfo.family + font.family: preferencesModel.defaultCodeFont + } + + Text + { + id: defaultResultFont + text: fontInfo.family + font.family: preferencesModel.defaultResultFont + } + } - DropDown + GroupBox + { + width: parent.width + + DropDown { id: interfaceFonts + label: qsTr("Interface:") values: preferencesModel.allInterfaceFonts addEmptyValue: true showEmptyValueAsNormal: true @@ -72,33 +97,12 @@ ScrollView onValueChanged: preferencesModel.interfaceFont = (currentIndex <= 0 ? "" : value) KeyNavigation.tab: codeFonts - - control.width: parent.width - (x + control.x) - - - Text - { - // If the defaultInterfaceFont does not exist on the machine, then the default font of the machine is used. - // This (invisible) Text item is just to ask what will be the real font used. - id: defaultInterfaceFont - font.family: preferencesModel.defaultInterfaceFont - text: fontInfo.family - visible: false - } } - } - - - Row - { - spacing: 3 * preferencesModel.uiScale - width: parent.width - - Text { id: codeTxt; width: fontGroup.maxText; text: qsTr("R, JAGS, or lavaan code:") } - + DropDown { id: codeFonts + label: qsTr("R, JAGS, or lavaan code:") values: preferencesModel.allCodeFonts addEmptyValue: true showEmptyValueAsNormal: true @@ -108,32 +112,12 @@ ScrollView onValueChanged: preferencesModel.codeFont = (currentIndex <= 0 ? "" : value) KeyNavigation.tab: resultFonts - - control.width: parent.width - (x + control.x) - - Text - { - id: defaultRCodeFont - text: fontInfo.family - font.family: preferencesModel.defaultCodeFont - visible: false - } - } - - } - - Row - { - spacing: 3 * preferencesModel.uiScale - width: parent.width - - Text { id: resultTxt; width: fontGroup.maxText; text: qsTr("Result & help:") } - DropDown { id: resultFonts + label: qsTr("Result & help:") values: preferencesModel.allResultFonts addEmptyValue: true showEmptyValueAsNormal: true @@ -143,16 +127,6 @@ ScrollView onValueChanged: preferencesModel.resultFont = (currentIndex <= 0 ? "" : value) KeyNavigation.tab: qtTextRendering - - control.width: parent.width - (x + control.x) - - Text - { - id: defaultResultFont - text: fontInfo.family - font.family: preferencesModel.defaultResultFont - visible: false - } } } @@ -207,24 +181,17 @@ ScrollView id: languageGroup title: qsTr("Preferred language") - Row + + DropDown { - spacing: 3 * preferencesModel.uiScale - width: parent.width - - Text { id: languageTxt; width: fontGroup.maxText; text: qsTr("Choose language ") } + id: languages + label: qsTr("Choose language ") + source: languageModel + startValue: languageModel.currentLanguage + onValueChanged: languageModel.currentLanguage = value - DropDown - { - id: languages - source: languageModel - startValue: languageModel.currentLanguage - onValueChanged: languageModel.currentLanguage = value - - KeyNavigation.tab: altnavcheckbox - - control.width: parent.width - (x + control.x) - } + KeyNavigation.tab: altnavcheckbox + } diff --git a/Desktop/components/JASP/Widgets/FilterConstructor/ComputedColumnsConstructor.qml b/Desktop/components/JASP/Widgets/FilterConstructor/ComputedColumnsConstructor.qml index 1df4633da3..9de6aa29bc 100644 --- a/Desktop/components/JASP/Widgets/FilterConstructor/ComputedColumnsConstructor.qml +++ b/Desktop/components/JASP/Widgets/FilterConstructor/ComputedColumnsConstructor.qml @@ -131,9 +131,11 @@ FocusScope anchors { - top: parent.top - left: parent.left - bottom: parent.bottom + top: parent.top + left: parent.left + bottom: parent.bottom + margins: columns.anchors.margins + bottomMargin: columns.anchors.bottomMargin } } @@ -141,10 +143,16 @@ FocusScope { id: columns model: columnsModel - anchors.top: parent.top - anchors.left: columnsLeftScrollBar.right - anchors.bottom: parent.bottom - width: maxWidth + width: maxWidth + anchors + { + top: parent.top + left: columnsLeftScrollBar.right + bottom: parent.bottom + margins: jaspTheme.contentMargin + bottomMargin: filterConstructor.extraSpaceUnderColumns + filterConstructor.blockDim + } + } } diff --git a/Desktop/components/JASP/Widgets/FilterConstructor/ElementView.qml b/Desktop/components/JASP/Widgets/FilterConstructor/ElementView.qml index b3cfa78c49..2b6adb715e 100644 --- a/Desktop/components/JASP/Widgets/FilterConstructor/ElementView.qml +++ b/Desktop/components/JASP/Widgets/FilterConstructor/ElementView.qml @@ -16,7 +16,7 @@ ListView delegate: MouseArea { - + implicitWidth: orientation === ListView.Horizontal ? elementLoader.item.width : ListView.view.width implicitHeight: orientation === ListView.Horizontal ? ListView.view.height : elementLoader.item.height diff --git a/Desktop/components/JASP/Widgets/FilterConstructor/FilterConstructor.qml b/Desktop/components/JASP/Widgets/FilterConstructor/FilterConstructor.qml index 9a79289bab..0ca632dd42 100644 --- a/Desktop/components/JASP/Widgets/FilterConstructor/FilterConstructor.qml +++ b/Desktop/components/JASP/Widgets/FilterConstructor/FilterConstructor.qml @@ -11,7 +11,8 @@ Item property real fontPixelSize: baseFontSize * preferencesModel.uiScale property real blockDim: baseBlockDim * preferencesModel.uiScale property var allKeys: ["number", "boolean", "string", "variable"] - readonly property real desiredMinimumHeight: operatorsRow.height + hints.height + applyFilter.height + (blockDim * 3) + readonly property real desiredMinimumHeight: operatorsRow.height + hints.height + applyFilter.height + blockDim * 4 + readonly property real desiredHeight: operatorsRow.height + hints.height + applyFilter.height + functieLijst.contentHeight property real extraSpaceUnderColumns: 0 property bool somethingChanged: false property bool isColumnConstructor: false @@ -151,9 +152,11 @@ Item anchors { - top: parent.top - left: parent.left - bottom: parent.bottom + top: parent.top + left: parent.left + bottom: parent.bottom + margins: columns.anchors.margins + bottomMargin: columns.anchors.bottomMargin } } @@ -161,10 +164,16 @@ Item { id: columns model: columnsModel - anchors.top: parent.top - anchors.left: columnsLeftScrollBar.right - anchors.bottom: parent.bottom - width: maxWidth + width: maxWidth + anchors + { + top: parent.top + left: columnsLeftScrollBar.right + bottom: parent.bottom + margins: jaspTheme.contentMargin + bottomMargin: filterConstructor.extraSpaceUnderColumns + filterConstructor.blockDim + } + } } @@ -325,7 +334,7 @@ Item top: parent.top right: functionsRightScrollBar.left bottom: parent.bottom - margins: 2 * preferencesModel.uiScale + margins: jaspTheme.contentMargin bottomMargin: filterConstructor.extraSpaceUnderColumns + filterConstructor.blockDim } diff --git a/Desktop/components/JASP/Widgets/FilterConstructor/Function.qml b/Desktop/components/JASP/Widgets/FilterConstructor/Function.qml index 5d939c0efb..661ddcff26 100644 --- a/Desktop/components/JASP/Widgets/FilterConstructor/Function.qml +++ b/Desktop/components/JASP/Widgets/FilterConstructor/Function.qml @@ -35,7 +35,8 @@ Item property var addNARMFunctions: ["mean", "sd", "var", "sum", "prod", "min", "max", "mean", "median"] property string extraParameterCode: addNARMFunctions.indexOf(functionName) >= 0 ? ", na.rm=TRUE" : "" - height: meanBar.height + Math.max(dropRow.height, filterConstructor.blockDim) + height: funcRoot.isRoot && !funcRoot.acceptsDrops ? filterConstructor.blockDim //If in the operatorselector bar then force same height as other operators + : meanBar.height + Math.max(dropRow.height, filterConstructor.blockDim) width: functionDef.width + haakjesLinks.width + dropRow.width + haakjesRechts.width + extraMeanWidth function shouldDrag(mouseX, mouseY) @@ -99,36 +100,36 @@ Item Text { - id: functionText + id: functionText - anchors.top: parent.top - anchors.bottom: parent.bottom + anchors.top: parent.top + anchors.bottom: parent.bottom color: jaspTheme.textEnabled - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter - text: funcRoot.drawMeanSpecial || funcRoot.isAbs || funcRoot.isRoot ? "" : friendlyFunctionName - font.pixelSize: filterConstructor.fontPixelSize - font.family: jaspTheme.font.family + text: funcRoot.drawMeanSpecial || funcRoot.isAbs || funcRoot.isRoot ? "" : friendlyFunctionName + font.pixelSize: filterConstructor.fontPixelSize + font.family: jaspTheme.font.family - visible: !functionImg.visible + visible: !functionImg.visible } Image { - id: functionImg + id: functionImg - visible: (!funcRoot.isRoot || !funcRoot.acceptsDrops) && functionImageSource !== "" + visible: (!funcRoot.isRoot || !funcRoot.acceptsDrops) && functionImageSource !== "" - source: functionImageSource + source: funcRoot.isRoot && !funcRoot.acceptsDrops ? jaspTheme.iconPath + "/sqrtSelector.png" : functionImageSource //workaround for operatorselector bar - height: filterConstructor.blockDim - width: height - sourceSize.width: filterConstructor.blockDim * 2 - sourceSize.height: filterConstructor.blockDim * 2 + height: filterConstructor.blockDim + width: height + sourceSize.width: filterConstructor.blockDim * 2 + sourceSize.height: filterConstructor.blockDim * 2 anchors.verticalCenter: parent.verticalCenter @@ -136,17 +137,17 @@ Item Image { - id: functionImgRoot + id: functionImgRoot - visible: funcRoot.isRoot && funcRoot.acceptsDrops + visible: funcRoot.isRoot && funcRoot.acceptsDrops - source: functionImageSource - anchors.top: parent.top - anchors.bottom: parent.bottom - width: filterConstructor.blockDim - sourceSize.width: filterConstructor.blockDim * 2 - sourceSize.height: filterConstructor.blockDim * 3 - smooth: true + source: functionImageSource + anchors.top: parent.top + anchors.bottom: parent.bottom + width: filterConstructor.blockDim + sourceSize.width: filterConstructor.blockDim * 2 + sourceSize.height: filterConstructor.blockDim * 3 + smooth: true } } diff --git a/Desktop/components/JASP/Widgets/FilterConstructor/OperatorDrag.qml b/Desktop/components/JASP/Widgets/FilterConstructor/OperatorDrag.qml index 3a884ccdb2..356c9ffb94 100644 --- a/Desktop/components/JASP/Widgets/FilterConstructor/OperatorDrag.qml +++ b/Desktop/components/JASP/Widgets/FilterConstructor/OperatorDrag.qml @@ -24,7 +24,7 @@ DragGeneric { property string operator: "+" property bool acceptsDrops: true - property var opImages: { '==': 'equal.png', '!=': 'notEqual.png', '<': 'lessThan.png', '>': 'greaterThan.png', '<=': 'lessThanEqual.png', '>=': 'greaterThanEqual.png', '&': 'and.png', '|': 'or.png', '%%': 'modulo.png', '%|%': 'ConditionBy.png'} + property var opImages: { '+': 'plus.png', '-': 'minus.png', '*': 'multiply.png', '==': 'equal.png', '!=': 'notEqual.png', '<': 'lessThan.png', '>': 'greaterThan.png', '<=': 'lessThanEqual.png', '>=': 'greaterThanEqual.png', '&': 'and.png', '|': 'or.png', '%%': 'modulo.png', '%|%': 'ConditionBy.png'} property alias leftDrop: showMe.leftDrop diff --git a/Desktop/components/JASP/Widgets/FilterConstructor/OperatorVertical.qml b/Desktop/components/JASP/Widgets/FilterConstructor/OperatorVertical.qml index 0957a6bf08..abd4d63a32 100644 --- a/Desktop/components/JASP/Widgets/FilterConstructor/OperatorVertical.qml +++ b/Desktop/components/JASP/Widgets/FilterConstructor/OperatorVertical.qml @@ -96,7 +96,7 @@ Item Image { id: opImg - y: leftDrop.y + leftDrop.height + 2 + y: (operator === "/" && !acceptsDrops) ? 0 : leftDrop.y + leftDrop.height + 2 visible: operatorImageSource !== "" && (operator !== "/" || !acceptsDrops) @@ -108,7 +108,7 @@ Item width: height anchors.horizontalCenter: parent.horizontalCenter } - + Item { id: opTextStripe diff --git a/Desktop/components/JASP/Widgets/FilterWindow.qml b/Desktop/components/JASP/Widgets/FilterWindow.qml index f908f3e79b..38dbbcac62 100644 --- a/Desktop/components/JASP/Widgets/FilterWindow.qml +++ b/Desktop/components/JASP/Widgets/FilterWindow.qml @@ -2,6 +2,7 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 import JASP.Controls 1.0 as JaspControls import "FilterConstructor" +import JASP FocusScope { @@ -11,8 +12,9 @@ FocusScope property bool opened: false property int minimumHeightTextBoxes: 50 * preferencesModel.uiScale property bool showEasyFilter: true - property int desiredMinimumHeight: easyFilterConstructor.desiredMinimumHeight// : rFilterFields.desiredMinimumHeight - + property int desiredMinimumHeight: easyFilterConstructor.desiredMinimumHeight + property int desiredHeight: easyFilterConstructor.desiredHeight + onShowEasyFilterChanged: if(!showEasyFilter) absorbModelRFilter() onVisibleChanged: if(!visible) filterWindow.close() @@ -27,9 +29,6 @@ FocusScope { opened = !opened absorbModelRFilter() - - if(opened) - height = parent.height / 2 } function open() @@ -302,6 +301,11 @@ FocusScope TextArea { + RSyntaxHighlighterQuick + { + textDocument: filterGeneratedEdit.textDocument + } + id: filterGeneratedEdit anchors.top: filterGeneratedBox.top anchors.left: resetAllGeneratedFilters.right @@ -347,6 +351,11 @@ FocusScope TextArea { + RSyntaxHighlighterQuick + { + textDocument: filterEdit.textDocument + } + id: filterEdit height: contentHeight + 30 selectByMouse: true diff --git a/Desktop/components/JASP/Widgets/RCommanderWindow.qml b/Desktop/components/JASP/Widgets/RCommanderWindow.qml index 134b16be52..cc8907a622 100644 --- a/Desktop/components/JASP/Widgets/RCommanderWindow.qml +++ b/Desktop/components/JASP/Widgets/RCommanderWindow.qml @@ -109,7 +109,7 @@ Window width: outputScroll.width TextArea - { + { id: outputWindow text: rCmd.output font: jaspTheme.fontRCode @@ -120,6 +120,11 @@ Window selectByMouse: true readOnly: true + RSyntaxHighlighterQuick + { + textDocument: outputWindow.textDocument + } + anchors { left: parent.left @@ -192,6 +197,13 @@ Window TextArea { + + RSyntaxHighlighterQuick + { + textDocument: codeEntry.textDocument + } + + id: codeEntry font: jaspTheme.fontRCode color: jaspTheme.textEnabled diff --git a/Desktop/components/JASP/Widgets/VariablesWindow.qml b/Desktop/components/JASP/Widgets/VariablesWindow.qml index 34e4787fd0..7b9ff9aff0 100644 --- a/Desktop/components/JASP/Widgets/VariablesWindow.qml +++ b/Desktop/components/JASP/Widgets/VariablesWindow.qml @@ -33,7 +33,7 @@ FocusScope property real calculatedBaseHeight: (columnInfoTop.height + jaspTheme.generalAnchorMargin * 2) property real calculatedMinimumHeight: calculatedBaseHeight * 1.5 - property real calculatedPreferredHeight: calculatedBaseHeight * 3 + property real calculatedPreferredHeight: Math.max(parent.height / 2, calculatedBaseHeight * 4) property real calculatedMaximumHeight: !tabView.visible ? calculatedBaseHeight : 0.90 * parent.height Connections diff --git a/Desktop/data/asyncloader.cpp b/Desktop/data/asyncloader.cpp index 41851948ec..11b13fcfa7 100644 --- a/Desktop/data/asyncloader.cpp +++ b/Desktop/data/asyncloader.cpp @@ -44,6 +44,11 @@ void AsyncLoader::io(FileEvent *event) switch (event->operation()) { + case FileEvent::FileNew: + emit progress(tr("Loading New Data Set"), 0); + emit beginLoad(event); + break; + case FileEvent::FileOpen: emit progress(tr("Loading Data Set"), 0); emit beginLoad(event); diff --git a/Desktop/data/datasetloader.cpp b/Desktop/data/datasetloader.cpp index 115c13a2aa..6f37f87638 100644 --- a/Desktop/data/datasetloader.cpp +++ b/Desktop/data/datasetloader.cpp @@ -25,6 +25,8 @@ #include "importers/jaspimporterold.h" #include "importers/odsimporter.h" #include "importers/readstatimporter.h" +#include "importers/excelimporter.h" + #include @@ -51,6 +53,8 @@ Importer* DataSetLoader::getImporter(const string & locator, const string &ext) boost::iequals(ext,".txt") || boost::iequals(ext,".tsv")) return new CSVImporter(); if( boost::iequals(ext,".ods")) return new ODSImporter(); + if( boost::iequals(ext,".xls") || + boost::iequals(ext,".xlsx")) return new ExcelImporter(); if( ReadStatImporter::extSupported(ext)) return new ReadStatImporter(ext); return nullptr; //If NULL then JASP will try to load it as a .jasp file (if the extension matches) diff --git a/Desktop/data/fileevent.cpp b/Desktop/data/fileevent.cpp index 1922f15943..68bc9c3c46 100644 --- a/Desktop/data/fileevent.cpp +++ b/Desktop/data/fileevent.cpp @@ -129,7 +129,9 @@ QString FileEvent::getProgressMsg() const case Utils::FileType::txt: case Utils::FileType::tsv: case Utils::FileType::ods: return tr("Importing Data from %1").arg(FileTypeBaseToQString(_type).toUpper()); - case Utils::FileType::sav: + case Utils::FileType::xls: + case Utils::FileType::xlsx: return tr("Importing Excel File"); + case Utils::FileType::sav: case Utils::FileType::zsav: case Utils::FileType::por: return tr("Importing SPSS File"); case Utils::FileType::xpt: diff --git a/Desktop/data/fileevent.h b/Desktop/data/fileevent.h index 5bd0f8329b..548db9adc1 100644 --- a/Desktop/data/fileevent.h +++ b/Desktop/data/fileevent.h @@ -33,7 +33,7 @@ class FileEvent : public QObject Q_OBJECT public: - enum FileMode { FileSave, FileOpen, FileExportResults, FileExportData, FileGenerateData, FileSyncData, FileClose }; + enum FileMode { FileSave, FileNew, FileOpen, FileExportResults, FileExportData, FileGenerateData, FileSyncData, FileClose }; FileEvent(QObject *parent = nullptr, FileMode fileMode = FileEvent::FileOpen); virtual ~FileEvent(); diff --git a/Desktop/data/importers/csv/csv.cpp b/Desktop/data/importers/csv/csv.cpp index 3d1ce29b5d..360e6b744a 100644 --- a/Desktop/data/importers/csv/csv.cpp +++ b/Desktop/data/importers/csv/csv.cpp @@ -402,6 +402,7 @@ void CSV::determineNumRows() if (i >= _utf8BufferEndPos - 1) { + _utf8BufferEndPos = 0; bool success = readUtf8(); if (success) i = -1; @@ -535,6 +536,7 @@ bool CSV::readLine(vector &items) for (size_t index = 0; index < items.size(); index++) { string item = items.at(index); + boost::algorithm::replace_all(item, "\n", " "); // so we should not allow newlines in values right? if (item.size() >= 2 && item[0] == '"' && item[item.size()-1] == '"') item = item.substr(1, item.size()-2); items[index] = item; diff --git a/Desktop/data/importers/csvimporter.cpp b/Desktop/data/importers/csvimporter.cpp index f536036abb..165a27110f 100644 --- a/Desktop/data/importers/csvimporter.cpp +++ b/Desktop/data/importers/csvimporter.cpp @@ -30,11 +30,11 @@ CSVImporter::CSVImporter() : Importer() ImportDataSet* CSVImporter::loadFile(const string &locator, std::function progressCallback) { JASPTIMER_RESUME(CSVImporter::loadFile); - + ImportDataSet* result = new ImportDataSet(this); stringvec colNames; CSV csv(locator); - csv.open(); + csv.open(); csv.readLine(colNames); vector importColumns; diff --git a/Desktop/data/importers/excel/excel.cpp b/Desktop/data/importers/excel/excel.cpp new file mode 100644 index 0000000000..a5f1657194 --- /dev/null +++ b/Desktop/data/importers/excel/excel.cpp @@ -0,0 +1,119 @@ +// +// Copyright (C) 2013-2024 University of Amsterdam +// +// 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 +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include "excel.h" +#include "utilities/qutils.h" +#include + +#include +#include + +Excel::Excel(const std::string &locator) +{ + _path = locator; +} + +void Excel::open() +{ + QFileInfo fi(tq(_path)); + _fileSize = fi.size(); + + if (_fileSize < 0) + throw std::runtime_error("Could not access file"); + + if (_fileSize == 0) + throw std::runtime_error("File is empty"); +} + +void Excel::openWorkbook() +{ + QString xlsFilePath = tq(_path); + const char* utf8Path = _path.c_str(); //But it would be better to just use _path.c_str() directly if you need it. It is in utf8 in any case. + QString extension = QFileInfo(xlsFilePath).suffix().toLower(); + + int ret = 0; + if (extension == "xls") + ret = freexl_open(utf8Path, &_handle); + else if (extension == "xlsx") + ret = freexl_open_xlsx(utf8Path, &_handle); + else + throw std::runtime_error("Unsupported file format: " + fq(extension)); + + if(ret != FREEXL_OK) + throw std::runtime_error("Unexpected error while loading excel file, error code: " + std::to_string(ret)); +} + +void Excel::selectActiveWorksheet() +{ + int ret = freexl_select_active_worksheet(_handle, 0); // import the first worksheet(index=0) by default. + if (ret != FREEXL_OK) + throw std::runtime_error("Could not select active worksheet,\n error code: " + std::to_string(ret)); +} + +void Excel::getWorksheetDimensions(uint32_t &rows, uint16_t &cols) { + int ret = freexl_worksheet_dimensions(_handle, &rows, &cols); + + if (ret != FREEXL_OK) + throw std::runtime_error("Could not read worksheet dimensions, error code: " + std::to_string(ret)); + + _numCols = cols; //get cols count while read sheet +} + +void Excel::getCellValue(uint32_t &row, uint16_t &col, std::string &cellValue) +{ + FreeXL_CellValue cell; + int ret = freexl_get_cell_value(_handle, row, col, &cell); + + if (ret != FREEXL_OK) + cellValue = "ERROR " + std::to_string(ret); + + switch (cell.type) + { + case FREEXL_CELL_TEXT: + case FREEXL_CELL_SST_TEXT: + case FREEXL_CELL_DATE: // So we store it as a character for now until support for date types. + case FREEXL_CELL_DATETIME: + case FREEXL_CELL_TIME: + cellValue = cell.value.text_value; + cellValue = stringUtils::replaceBy(cellValue, "\n", "_"); + break; + case FREEXL_CELL_INT: + cellValue = std::to_string(cell.value.int_value); + break; + case FREEXL_CELL_DOUBLE: + cellValue = std::to_string(cell.value.double_value); + break; + case FREEXL_CELL_NULL: + default: + cellValue = ""; + break; + } +} + +uint16_t Excel::countCols() +{ + return _numCols; +} + +void Excel::close() +{ + if (_handle) + { + freexl_close(_handle); + _handle = nullptr; + } +} diff --git a/Desktop/data/importers/excel/excel.h b/Desktop/data/importers/excel/excel.h new file mode 100644 index 0000000000..9eebfb16e3 --- /dev/null +++ b/Desktop/data/importers/excel/excel.h @@ -0,0 +1,53 @@ +// +// Copyright (C) 2013-2024 University of Amsterdam +// +// 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 +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef EXCEL_H +#define EXCEL_H + +#include +#include + +#include + +class Excel +{ +public: + Excel(const std::string &path); + + void open(); + void close(); + + void openWorkbook(); + void selectActiveWorksheet(); + void getWorksheetDimensions(uint32_t &rows, uint16_t &cols); + void getCellValue(uint32_t &row, uint16_t &col, std::string &cellValue); + + uint16_t countCols(); + +private: + + long _fileSize; + long _filePosition; + uint16_t _numCols; + +private: + + std::string _path; + const void *_handle; +}; + +#endif // EXCEL_H diff --git a/Desktop/data/importers/excel/excelimportcolumn.cpp b/Desktop/data/importers/excel/excelimportcolumn.cpp new file mode 100644 index 0000000000..a9cf48a2f8 --- /dev/null +++ b/Desktop/data/importers/excel/excelimportcolumn.cpp @@ -0,0 +1,31 @@ +#include "excelimportcolumn.h" +#include "timers.h" + +ExcelImportColumn::ExcelImportColumn(ImportDataSet* importDataSet, std::string name) : ImportColumn(importDataSet, name) +{ +} + +ExcelImportColumn::ExcelImportColumn(ImportDataSet *importDataSet, std::string name, long reserve) : ImportColumn(importDataSet, name) +{ + _data.reserve(reserve); +} + +ExcelImportColumn::~ExcelImportColumn() +{ + JASPTIMER_SCOPE(ExcelImportColumn::~ExcelImportColumn()); +} + +size_t ExcelImportColumn::size() const +{ + return _data.size(); +} + +void ExcelImportColumn::addValue(const std::string &value) +{ + _data.push_back(value); +} + +const std::vector &ExcelImportColumn::getValues() const +{ + return _data; +} diff --git a/Desktop/data/importers/excel/excelimportcolumn.h b/Desktop/data/importers/excel/excelimportcolumn.h new file mode 100644 index 0000000000..c84a563c09 --- /dev/null +++ b/Desktop/data/importers/excel/excelimportcolumn.h @@ -0,0 +1,26 @@ +#ifndef EXCELIMPORTCOLUMN_H +#define EXCELIMPORTCOLUMN_H + +#include "data/importers/importcolumn.h" + + +class ExcelImportColumn : public ImportColumn +{ +public: + ExcelImportColumn(ImportDataSet* importDataSet, std::string name); + ExcelImportColumn(ImportDataSet* importDataSet, std::string name, long reserve); + ~ExcelImportColumn() override; + + size_t size() const override; + const stringvec & allValuesAsStrings() const override { return _data; } + void addValue(const std::string &value); + const stringvec & getValues() const; + + +private: + stringvec _data; + +}; + + +#endif // EXCELIMPORTCOLUMN_H diff --git a/Desktop/data/importers/excelimporter.cpp b/Desktop/data/importers/excelimporter.cpp new file mode 100644 index 0000000000..f159407a0d --- /dev/null +++ b/Desktop/data/importers/excelimporter.cpp @@ -0,0 +1,106 @@ +// +// Copyright (C) 2013-2024 University of Amsterdam +// +// 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 +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include "excelimporter.h" +#include "data/importers/excel/excel.h" +#include "data/importers/excel/excelimportcolumn.h" +#include +#include +#include +#include + + +ExcelImporter::ExcelImporter() : Importer() {} + +ImportDataSet* ExcelImporter::loadFile(const std::string &locator, std::function progressCallback) +{ + JASPTIMER_RESUME(ExcelImporter::loadFile); + + ImportDataSet* data = new ImportDataSet(this); + stringvec colNames; + + uint16_t cols; + uint32_t rows; + uint32_t row; + uint16_t col; + + std::vector importColumns; + + Excel excel(locator); + excel.open(); + progressCallback(3); + + excel.openWorkbook(); + progressCallback(5); + + excel.selectActiveWorksheet(); + progressCallback(10); + + excel.getWorksheetDimensions(rows, cols); + progressCallback(25); + + cols = excel.countCols(); + importColumns.reserve(cols); + + for (uint32_t row = 0; row < rows; ++row) + { + stringvec lineValues; + + for (uint16_t col = 0; col < cols; ++col) + { + std::string cellValue; + excel.getCellValue(row, col, cellValue); + lineValues.push_back(cellValue); + } + + if (row == 0) + { + colNames = lineValues; + importColumns.reserve(colNames.size()); + + for (int i = 0; i < colNames.size(); ++i) + { + std::string colName = colNames[i]; + if (colName.empty()) + colName = "V" + std::to_string(i + 1); + else if(ColumnUtils::isIntValue(colName) || ColumnUtils::isDoubleValue(colName)) + colName = "V" + colName; + // distinguish duplicate column names + if(std::find(colNames.begin(), colNames.begin() + i, colName) != colNames.begin() + i) + colName += "_" + std::to_string(i + 1); + + colNames[i] = colName; + importColumns.push_back(new ExcelImportColumn(data, colName, rows - 1)); + } + } + else + { + for (int i = 0; i < importColumns.size(); ++i) + importColumns[i]->addValue(i < lineValues.size() ? lineValues[i] : ""); + } + } + + for (ExcelImportColumn* col : importColumns) + data->addColumn(col); + + data->buildDictionary(); + excel.close(); + + JASPTIMER_STOP(ExcelImporter::loadFile); + + return data; +} diff --git a/Desktop/data/importers/excelimporter.h b/Desktop/data/importers/excelimporter.h new file mode 100644 index 0000000000..52b0c31dfa --- /dev/null +++ b/Desktop/data/importers/excelimporter.h @@ -0,0 +1,40 @@ +// +// Copyright (C) 2013-2024 University of Amsterdam +// +// 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 +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef EXCELIMPORTER_H +#define EXCELIMPORTER_H + +#include "importer.h" +#include +#include "timers.h" + + +class ExcelImporter : public Importer +{ + Q_DECLARE_TR_FUNCTIONS(ExcelImporter) +public: + ExcelImporter(); + virtual ~ExcelImporter() {} + +protected: + ImportDataSet* loadFile(const std::string &locator, std::function progressCallback) override; + +private: + JASPTIMER_CLASS(ExcelImporter); +}; + +#endif // EXCELIMPORTER_H diff --git a/Desktop/data/importers/importer.cpp b/Desktop/data/importers/importer.cpp index 6bfce2ba0a..3a5c6b7016 100644 --- a/Desktop/data/importers/importer.cpp +++ b/Desktop/data/importers/importer.cpp @@ -15,6 +15,8 @@ Importer::~Importer() {} void Importer::loadDataSet(const std::string &locator, std::function progressCallback) { + long timeBeginS = Utils::currentSeconds(); + DataSetPackage::pkg()->beginLoadingData(); _synching = false; @@ -52,6 +54,9 @@ void Importer::loadDataSet(const std::string &locator, std::function importDataSet->clearColumns(); delete importDataSet; DataSetPackage::pkg()->endLoadingData(); + + long totalS = (Utils::currentSeconds() - timeBeginS); + Log::log() << "Loading '" << locator << "' took " << totalS << "s or " << (totalS / 60) << "m" << std::endl; } void Importer::initColumn(QVariant colId, ImportColumn *importColumn) @@ -73,6 +78,7 @@ void Importer::initColumnWithStrings(QVariant colId, const std::string &newName, void Importer::syncDataSet(const std::string &locator, std::function progress) { _synching = true; + long timeBeginS = Utils::currentSeconds(); ImportDataSet * importDataSet = loadFile(locator, progress); bool rowCountChanged = importDataSet->rowCount() != DataSetPackage::pkg()->dataRowCount(); @@ -135,6 +141,9 @@ void Importer::syncDataSet(const std::string &locator, std::function DataSetPackage::pkg()->setManualEdits(false); delete importDataSet; + + long totalS = (Utils::currentSeconds() - timeBeginS); + Log::log() << "Synching '" << locator << "' took " << totalS << "s or " << (totalS / 60) << "m" << std::endl; } void Importer::_syncPackage( diff --git a/Desktop/html/css/highlight-default.min.css b/Desktop/html/css/highlight-default.min.css index 69edcf1baa..03b6da8bf4 100644 --- a/Desktop/html/css/highlight-default.min.css +++ b/Desktop/html/css/highlight-default.min.css @@ -1,9 +1,10 @@ -/*! - Theme: Default - Description: Original highlight.js style - Author: (c) Ivan Sagalaev - Maintainer: @highlightjs/core-team - Website: https://highlightjs.org/ - License: see project LICENSE - Touched: 2021 -*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#f3f3f3;color:#444}.hljs-comment{color:#697070}.hljs-punctuation,.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:#695}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub Dark + Description: Dark theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-dark + Current colors taken from GitHub's CSS +*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c} \ No newline at end of file diff --git a/Desktop/html/css/jasp.css b/Desktop/html/css/jasp.css index c985a7c1f6..5d3c2b83b9 100644 --- a/Desktop/html/css/jasp.css +++ b/Desktop/html/css/jasp.css @@ -655,3 +655,9 @@ iframe.ql-video { transform: translateX(0); } } + +/* we hack the quill editor code-block style */ +.ql-snow .ql-editor .ql-code-block-container { + background-color: #333333 !important; + color: #f8f8f2 !important; +} \ No newline at end of file diff --git a/Desktop/html/css/quill.snow.css b/Desktop/html/css/quill.snow.css index 8c66ec615d..d06fe4f570 100644 --- a/Desktop/html/css/quill.snow.css +++ b/Desktop/html/css/quill.snow.css @@ -1,958 +1,8 @@ /*! - * - * Quill Editor v1.3.1 - * https://quilljs.com/ + * Quill Editor v2.0.2 + * https://quilljs.com + * Copyright (c) 2017-2024, Slab * Copyright (c) 2014, Jason Chen * Copyright (c) 2013, salesforce.com */ - .ql-container { - box-sizing: border-box; - font-family: Helvetica, Arial, sans-serif; - font-size: 13px; - height: 100%; - margin: 0px; - position: relative; -} -.ql-container.ql-disabled .ql-tooltip { - visibility: hidden; -} -.ql-container.ql-disabled .ql-editor ul[data-checked] > li::before { - pointer-events: none; -} -.ql-clipboard { - left: -100000px; - height: 1px; - overflow-y: hidden; - position: absolute; - top: 50%; -} -.ql-clipboard p { - margin: 0; - padding: 0; -} -.ql-editor { - box-sizing: border-box; - line-height: 1.42; - height: 100%; - outline: none; - overflow-y: auto; - padding: 12px 15px; - tab-size: 4; - -moz-tab-size: 4; - text-align: left; - white-space: pre-wrap; - word-wrap: break-word; -} -.ql-editor > * { - cursor: text; -} -.ql-editor p, -.ql-editor ol, -.ql-editor ul, -.ql-editor pre, -.ql-editor blockquote, -.ql-editor h1, -.ql-editor h2, -.ql-editor h3, -.ql-editor h4, -.ql-editor h5, -.ql-editor h6 { - margin: 0; - padding: 0; - counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; -} -.ql-editor ol, -.ql-editor ul { - padding-left: 1.5em; -} -.ql-editor ol > li, -.ql-editor ul > li { - list-style-type: none; -} -.ql-editor ul > li::before { - content: '\2022'; -} -.ql-editor ul[data-checked=true], -.ql-editor ul[data-checked=false] { - pointer-events: none; -} -.ql-editor ul[data-checked=true] > li *, -.ql-editor ul[data-checked=false] > li * { - pointer-events: all; -} -.ql-editor ul[data-checked=true] > li::before, -.ql-editor ul[data-checked=false] > li::before { - color: #777; - cursor: pointer; - pointer-events: all; -} -.ql-editor ul[data-checked=true] > li::before { - content: '\2611'; -} -.ql-editor ul[data-checked=false] > li::before { - content: '\2610'; -} -.ql-editor li::before { - display: inline-block; - white-space: nowrap; - width: 1.2em; -} -.ql-editor li:not(.ql-direction-rtl)::before { - margin-left: -1.5em; - margin-right: 0.3em; - text-align: right; -} -.ql-editor li.ql-direction-rtl::before { - margin-left: 0.3em; - margin-right: -1.5em; -} -.ql-editor ol li:not(.ql-direction-rtl), -.ql-editor ul li:not(.ql-direction-rtl) { - padding-left: 1.5em; -} -.ql-editor ol li.ql-direction-rtl, -.ql-editor ul li.ql-direction-rtl { - padding-right: 1.5em; -} -.ql-editor ol li { - counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; - counter-increment: list-0; -} -.ql-editor ol li:before { - content: counter(list-0, decimal) '. '; -} -.ql-editor ol li.ql-indent-1 { - counter-increment: list-1; -} -.ql-editor ol li.ql-indent-1:before { - content: counter(list-1, lower-alpha) '. '; -} -.ql-editor ol li.ql-indent-1 { - counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9; -} -.ql-editor ol li.ql-indent-2 { - counter-increment: list-2; -} -.ql-editor ol li.ql-indent-2:before { - content: counter(list-2, lower-roman) '. '; -} -.ql-editor ol li.ql-indent-2 { - counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9; -} -.ql-editor ol li.ql-indent-3 { - counter-increment: list-3; -} -.ql-editor ol li.ql-indent-3:before { - content: counter(list-3, decimal) '. '; -} -.ql-editor ol li.ql-indent-3 { - counter-reset: list-4 list-5 list-6 list-7 list-8 list-9; -} -.ql-editor ol li.ql-indent-4 { - counter-increment: list-4; -} -.ql-editor ol li.ql-indent-4:before { - content: counter(list-4, lower-alpha) '. '; -} -.ql-editor ol li.ql-indent-4 { - counter-reset: list-5 list-6 list-7 list-8 list-9; -} -.ql-editor ol li.ql-indent-5 { - counter-increment: list-5; -} -.ql-editor ol li.ql-indent-5:before { - content: counter(list-5, lower-roman) '. '; -} -.ql-editor ol li.ql-indent-5 { - counter-reset: list-6 list-7 list-8 list-9; -} -.ql-editor ol li.ql-indent-6 { - counter-increment: list-6; -} -.ql-editor ol li.ql-indent-6:before { - content: counter(list-6, decimal) '. '; -} -.ql-editor ol li.ql-indent-6 { - counter-reset: list-7 list-8 list-9; -} -.ql-editor ol li.ql-indent-7 { - counter-increment: list-7; -} -.ql-editor ol li.ql-indent-7:before { - content: counter(list-7, lower-alpha) '. '; -} -.ql-editor ol li.ql-indent-7 { - counter-reset: list-8 list-9; -} -.ql-editor ol li.ql-indent-8 { - counter-increment: list-8; -} -.ql-editor ol li.ql-indent-8:before { - content: counter(list-8, lower-roman) '. '; -} -.ql-editor ol li.ql-indent-8 { - counter-reset: list-9; -} -.ql-editor ol li.ql-indent-9 { - counter-increment: list-9; -} -.ql-editor ol li.ql-indent-9:before { - content: counter(list-9, decimal) '. '; -} -.ql-editor .ql-indent-1:not(.ql-direction-rtl) { - padding-left: 3em; -} -.ql-editor li.ql-indent-1:not(.ql-direction-rtl) { - padding-left: 4.5em; -} -.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right { - padding-right: 3em; -} -.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right { - padding-right: 4.5em; -} -.ql-editor .ql-indent-2:not(.ql-direction-rtl) { - padding-left: 6em; -} -.ql-editor li.ql-indent-2:not(.ql-direction-rtl) { - padding-left: 7.5em; -} -.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right { - padding-right: 6em; -} -.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right { - padding-right: 7.5em; -} -.ql-editor .ql-indent-3:not(.ql-direction-rtl) { - padding-left: 9em; -} -.ql-editor li.ql-indent-3:not(.ql-direction-rtl) { - padding-left: 10.5em; -} -.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right { - padding-right: 9em; -} -.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right { - padding-right: 10.5em; -} -.ql-editor .ql-indent-4:not(.ql-direction-rtl) { - padding-left: 12em; -} -.ql-editor li.ql-indent-4:not(.ql-direction-rtl) { - padding-left: 13.5em; -} -.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right { - padding-right: 12em; -} -.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right { - padding-right: 13.5em; -} -.ql-editor .ql-indent-5:not(.ql-direction-rtl) { - padding-left: 15em; -} -.ql-editor li.ql-indent-5:not(.ql-direction-rtl) { - padding-left: 16.5em; -} -.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right { - padding-right: 15em; -} -.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right { - padding-right: 16.5em; -} -.ql-editor .ql-indent-6:not(.ql-direction-rtl) { - padding-left: 18em; -} -.ql-editor li.ql-indent-6:not(.ql-direction-rtl) { - padding-left: 19.5em; -} -.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right { - padding-right: 18em; -} -.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right { - padding-right: 19.5em; -} -.ql-editor .ql-indent-7:not(.ql-direction-rtl) { - padding-left: 21em; -} -.ql-editor li.ql-indent-7:not(.ql-direction-rtl) { - padding-left: 22.5em; -} -.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right { - padding-right: 21em; -} -.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right { - padding-right: 22.5em; -} -.ql-editor .ql-indent-8:not(.ql-direction-rtl) { - padding-left: 24em; -} -.ql-editor li.ql-indent-8:not(.ql-direction-rtl) { - padding-left: 25.5em; -} -.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right { - padding-right: 24em; -} -.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right { - padding-right: 25.5em; -} -.ql-editor .ql-indent-9:not(.ql-direction-rtl) { - padding-left: 27em; -} -.ql-editor li.ql-indent-9:not(.ql-direction-rtl) { - padding-left: 28.5em; -} -.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right { - padding-right: 27em; -} -.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right { - padding-right: 28.5em; -} -.ql-editor .ql-video { - display: block; - max-width: 100%; -} -.ql-editor .ql-video.ql-align-center { - margin: 0 auto; -} -.ql-editor .ql-video.ql-align-right { - margin: 0 0 0 auto; -} -.ql-editor .ql-bg-black { - background-color: #000; -} -.ql-editor .ql-bg-red { - background-color: #e60000; -} -.ql-editor .ql-bg-orange { - background-color: #f90; -} -.ql-editor .ql-bg-yellow { - background-color: #ff0; -} -.ql-editor .ql-bg-green { - background-color: #008a00; -} -.ql-editor .ql-bg-blue { - background-color: #06c; -} -.ql-editor .ql-bg-purple { - background-color: #93f; -} -.ql-editor .ql-color-white { - color: #fff; -} -.ql-editor .ql-color-red { - color: #e60000; -} -.ql-editor .ql-color-orange { - color: #f90; -} -.ql-editor .ql-color-yellow { - color: #ff0; -} -.ql-editor .ql-color-green { - color: #008a00; -} -.ql-editor .ql-color-blue { - color: #06c; -} -.ql-editor .ql-color-purple { - color: #93f; -} -.ql-editor .ql-font-serif { - font-family: Georgia, Times New Roman, serif; -} -.ql-editor .ql-font-monospace { - font-family: Monaco, Courier New, monospace; -} -.ql-editor .ql-size-small { - font-size: 0.75em; -} -.ql-editor .ql-size-large { - font-size: 1.5em; -} -.ql-editor .ql-size-huge { - font-size: 2.5em; -} -.ql-editor .ql-direction-rtl { - direction: rtl; - text-align: inherit; -} -.ql-editor .ql-align-center { - text-align: center; -} -.ql-editor .ql-align-justify { - text-align: justify; -} -.ql-editor .ql-align-right { - text-align: right; -} -.ql-editor .ql-embed-selected { - border: 1px solid #777; - user-select: none; -} -.ql-editor.ql-blank::before { - color: rgba(0,0,0,0.6); - content: attr(data-placeholder); - font-style: italic; - pointer-events: none; - position: absolute; -} -.ql-snow.ql-toolbar:after, -.ql-snow .ql-toolbar:after { - clear: both; - content: ''; - display: table; -} -.ql-snow.ql-toolbar button, -.ql-snow .ql-toolbar button { - background: none; - border: none; - cursor: pointer; - display: inline-block; - float: left; - height: 24px; - padding: 3px 5px; - width: 28px; -} -.ql-snow.ql-toolbar button svg, -.ql-snow .ql-toolbar button svg { - float: left; - height: 100%; -} -.ql-snow.ql-toolbar button:active:hover, -.ql-snow .ql-toolbar button:active:hover { - outline: none; -} -.ql-snow.ql-toolbar input.ql-image[type=file], -.ql-snow .ql-toolbar input.ql-image[type=file] { - display: none; -} -.ql-snow.ql-toolbar button:hover, -.ql-snow .ql-toolbar button:hover, -.ql-snow.ql-toolbar button:focus, -.ql-snow .ql-toolbar button:focus, -.ql-snow.ql-toolbar button.ql-active, -.ql-snow .ql-toolbar button.ql-active, -.ql-snow.ql-toolbar .ql-picker-label:hover, -.ql-snow .ql-toolbar .ql-picker-label:hover, -.ql-snow.ql-toolbar .ql-picker-label.ql-active, -.ql-snow .ql-toolbar .ql-picker-label.ql-active, -.ql-snow.ql-toolbar .ql-picker-item:hover, -.ql-snow .ql-toolbar .ql-picker-item:hover, -.ql-snow.ql-toolbar .ql-picker-item.ql-selected, -.ql-snow .ql-toolbar .ql-picker-item.ql-selected { - color: #06c; -} -.ql-snow.ql-toolbar button:hover .ql-fill, -.ql-snow .ql-toolbar button:hover .ql-fill, -.ql-snow.ql-toolbar button:focus .ql-fill, -.ql-snow .ql-toolbar button:focus .ql-fill, -.ql-snow.ql-toolbar button.ql-active .ql-fill, -.ql-snow .ql-toolbar button.ql-active .ql-fill, -.ql-snow.ql-toolbar .ql-picker-label:hover .ql-fill, -.ql-snow .ql-toolbar .ql-picker-label:hover .ql-fill, -.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-fill, -.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-fill, -.ql-snow.ql-toolbar .ql-picker-item:hover .ql-fill, -.ql-snow .ql-toolbar .ql-picker-item:hover .ql-fill, -.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-fill, -.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-fill, -.ql-snow.ql-toolbar button:hover .ql-stroke.ql-fill, -.ql-snow .ql-toolbar button:hover .ql-stroke.ql-fill, -.ql-snow.ql-toolbar button:focus .ql-stroke.ql-fill, -.ql-snow .ql-toolbar button:focus .ql-stroke.ql-fill, -.ql-snow.ql-toolbar button.ql-active .ql-stroke.ql-fill, -.ql-snow .ql-toolbar button.ql-active .ql-stroke.ql-fill, -.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill, -.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill, -.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill, -.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill, -.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill, -.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill, -.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill, -.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill { - fill: #06c; -} -.ql-snow.ql-toolbar button:hover .ql-stroke, -.ql-snow .ql-toolbar button:hover .ql-stroke, -.ql-snow.ql-toolbar button:focus .ql-stroke, -.ql-snow .ql-toolbar button:focus .ql-stroke, -.ql-snow.ql-toolbar button.ql-active .ql-stroke, -.ql-snow .ql-toolbar button.ql-active .ql-stroke, -.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke, -.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke, -.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke, -.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke, -.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke, -.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke, -.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke, -.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke, -.ql-snow.ql-toolbar button:hover .ql-stroke-miter, -.ql-snow .ql-toolbar button:hover .ql-stroke-miter, -.ql-snow.ql-toolbar button:focus .ql-stroke-miter, -.ql-snow .ql-toolbar button:focus .ql-stroke-miter, -.ql-snow.ql-toolbar button.ql-active .ql-stroke-miter, -.ql-snow .ql-toolbar button.ql-active .ql-stroke-miter, -.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke-miter, -.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke-miter, -.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter, -.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter, -.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke-miter, -.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke-miter, -.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter, -.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter { - stroke: #06c; -} -@media (pointer: coarse) { - .ql-snow.ql-toolbar button:hover:not(.ql-active), - .ql-snow .ql-toolbar button:hover:not(.ql-active) { - color: #444; - } - .ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-fill, - .ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-fill, - .ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill, - .ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill { - fill: #444; - } - .ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke, - .ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke, - .ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter, - .ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter { - stroke: #444; - } -} -.ql-snow { - box-sizing: border-box; -} -.ql-snow * { - box-sizing: border-box; -} -.ql-snow .ql-hidden { - display: none; -} -.ql-snow .ql-out-bottom, -.ql-snow .ql-out-top { - visibility: hidden; -} -.ql-snow .ql-tooltip { - position: absolute; - transform: translateY(10px); -} -.ql-snow .ql-tooltip a { - cursor: pointer; - text-decoration: none; -} -.ql-snow .ql-tooltip.ql-flip { - transform: translateY(-10px); -} -.ql-snow .ql-formats { - display: inline-block; - vertical-align: middle; -} -.ql-snow .ql-formats:after { - clear: both; - content: ''; - display: table; -} -.ql-snow .ql-stroke { - fill: none; - stroke: #444; - stroke-linecap: round; - stroke-linejoin: round; - stroke-width: 2; -} -.ql-snow .ql-stroke-miter { - fill: none; - stroke: #444; - stroke-miterlimit: 10; - stroke-width: 2; -} -.ql-snow .ql-fill, -.ql-snow .ql-stroke.ql-fill { - fill: #444; -} -.ql-snow .ql-empty { - fill: none; -} -.ql-snow .ql-even { - fill-rule: evenodd; -} -.ql-snow .ql-thin, -.ql-snow .ql-stroke.ql-thin { - stroke-width: 1; -} -.ql-snow .ql-transparent { - opacity: 0.4; -} -.ql-snow .ql-direction svg:last-child { - display: none; -} -.ql-snow .ql-direction.ql-active svg:last-child { - display: inline; -} -.ql-snow .ql-direction.ql-active svg:first-child { - display: none; -} -.ql-snow .ql-editor h1 { - font-size: 2em; -} -.ql-snow .ql-editor h2 { - font-size: 1.5em; -} -.ql-snow .ql-editor h3 { - font-size: 1.17em; -} -.ql-snow .ql-editor h4 { - font-size: 1em; -} -.ql-snow .ql-editor h5 { - font-size: 0.83em; -} -.ql-snow .ql-editor h6 { - font-size: 0.67em; -} -.ql-snow .ql-editor a { - text-decoration: underline; -} -.ql-snow .ql-editor blockquote { - border-left: 4px solid #ccc; - margin-bottom: 5px; - margin-top: 5px; - padding-left: 16px; -} -.ql-snow .ql-editor code, -.ql-snow .ql-editor pre { - background-color: #f0f0f0; - border-radius: 3px; -} -.ql-snow .ql-editor pre { - white-space: pre-wrap; - margin-bottom: 5px; - margin-top: 5px; - padding: 5px 10px; -} -.ql-snow .ql-editor code { - font-size: 85%; - padding: 2px 4px; -} -.ql-snow .ql-editor pre.ql-syntax { - background-color: #23241f; - color: #f8f8f2; - overflow: visible; -} -.ql-snow .ql-editor img { - max-width: 100%; -} -.ql-snow .ql-picker { - color: #444; - display: inline-block; - float: left; - font-size: 14px; - font-weight: 500; - height: 24px; - position: relative; - vertical-align: middle; -} -.ql-snow .ql-picker-label { - cursor: pointer; - display: inline-block; - height: 100%; - padding-left: 8px; - padding-right: 2px; - position: relative; - width: 100%; -} -.ql-snow .ql-picker-label::before { - display: inline-block; - line-height: 22px; -} -.ql-snow .ql-picker-options { - background-color: #fff; - display: none; - min-width: 100%; - padding: 4px 8px; - position: absolute; - white-space: nowrap; -} -.ql-snow .ql-picker-options .ql-picker-item { - cursor: pointer; - display: block; - padding-bottom: 5px; - padding-top: 5px; -} -.ql-snow .ql-picker.ql-expanded .ql-picker-label { - color: #ccc; - z-index: 2; -} -.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-fill { - fill: #ccc; -} -.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-stroke { - stroke: #ccc; -} -.ql-snow .ql-picker.ql-expanded .ql-picker-options { - display: block; - margin-top: -1px; - top: 100%; - z-index: 1; -} -.ql-snow .ql-color-picker, -.ql-snow .ql-icon-picker { - width: 28px; -} -.ql-snow .ql-color-picker .ql-picker-label, -.ql-snow .ql-icon-picker .ql-picker-label { - padding: 2px 4px; -} -.ql-snow .ql-color-picker .ql-picker-label svg, -.ql-snow .ql-icon-picker .ql-picker-label svg { - right: 4px; -} -.ql-snow .ql-icon-picker .ql-picker-options { - padding: 4px 0px; -} -.ql-snow .ql-icon-picker .ql-picker-item { - height: 24px; - width: 24px; - padding: 2px 4px; -} -.ql-snow .ql-color-picker .ql-picker-options { - padding: 3px 5px; - width: 152px; -} -.ql-snow .ql-color-picker .ql-picker-item { - border: 1px solid transparent; - float: left; - height: 16px; - margin: 2px; - padding: 0px; - width: 16px; -} -.ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg { - position: absolute; - margin-top: -9px; - right: 0; - top: 50%; - width: 18px; -} -.ql-snow .ql-picker.ql-header .ql-picker-label[data-label]:not([data-label=''])::before, -.ql-snow .ql-picker.ql-font .ql-picker-label[data-label]:not([data-label=''])::before, -.ql-snow .ql-picker.ql-size .ql-picker-label[data-label]:not([data-label=''])::before, -.ql-snow .ql-picker.ql-header .ql-picker-item[data-label]:not([data-label=''])::before, -.ql-snow .ql-picker.ql-font .ql-picker-item[data-label]:not([data-label=''])::before, -.ql-snow .ql-picker.ql-size .ql-picker-item[data-label]:not([data-label=''])::before { - content: attr(data-label); -} -.ql-snow .ql-picker.ql-header { - width: 98px; -} -.ql-snow .ql-picker.ql-header .ql-picker-label::before, -.ql-snow .ql-picker.ql-header .ql-picker-item::before { - content: 'Normal'; -} -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { - content: 'Heading 1'; -} -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { - content: 'Heading 2'; -} -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { - content: 'Heading 3'; -} -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { - content: 'Heading 4'; -} -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { - content: 'Heading 5'; -} -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { - content: 'Heading 6'; -} -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { - font-size: 2em; -} -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { - font-size: 1.5em; -} -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { - font-size: 1.17em; -} -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { - font-size: 1em; -} -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { - font-size: 0.83em; -} -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { - font-size: 0.67em; -} -.ql-snow .ql-picker.ql-font { - width: 108px; -} -.ql-snow .ql-picker.ql-font .ql-picker-label::before, -.ql-snow .ql-picker.ql-font .ql-picker-item::before { - content: 'Sans Serif'; -} -.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before, -.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before { - content: 'Serif'; -} -.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before, -.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before { - content: 'Monospace'; -} -.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before { - font-family: Georgia, Times New Roman, serif; -} -.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before { - font-family: Monaco, Courier New, monospace; -} -.ql-snow .ql-picker.ql-size { - width: 98px; -} -.ql-snow .ql-picker.ql-size .ql-picker-label::before, -.ql-snow .ql-picker.ql-size .ql-picker-item::before { - content: 'Normal'; -} -.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before, -.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before { - content: 'Small'; -} -.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before, -.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before { - content: 'Large'; -} -.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before, -.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before { - content: 'Huge'; -} -.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before { - font-size: 10px; -} -.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before { - font-size: 18px; -} -.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before { - font-size: 32px; -} -.ql-snow .ql-color-picker.ql-background .ql-picker-item { - background-color: #fff; -} -.ql-snow .ql-color-picker.ql-color .ql-picker-item { - background-color: #000; -} -.ql-toolbar.ql-snow { - border: 1px solid #ccc; - box-sizing: border-box; - font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; - padding: 8px; -} -.ql-toolbar.ql-snow .ql-formats { - margin-right: 15px; -} -.ql-toolbar.ql-snow .ql-picker-label { - border: 1px solid transparent; -} -.ql-toolbar.ql-snow .ql-picker-options { - border: 1px solid transparent; - box-shadow: rgba(0,0,0,0.2) 0 2px 8px; -} -.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label { - border-color: #ccc; -} -.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options { - border-color: #ccc; -} -.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item.ql-selected, -.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item:hover { - border-color: #000; -} -.ql-toolbar.ql-snow + .ql-container.ql-snow { - border-top: 0px; -} -.ql-snow .ql-tooltip { - background-color: #fff; - border: 1px solid #ccc; - box-shadow: 0px 0px 5px #ddd; - color: #444; - padding: 5px 12px; - white-space: nowrap; -} -.ql-snow .ql-tooltip::before { - content: "Visit URL:"; - line-height: 26px; - margin-right: 8px; -} -.ql-snow .ql-tooltip input[type=text] { - display: none; - border: 1px solid #ccc; - font-size: 13px; - height: 26px; - margin: 0px; - padding: 3px 5px; - width: 170px; -} -.ql-snow .ql-tooltip a { - display: inline-block; - max-width: 200px; - overflow-x: hidden; - text-overflow: ellipsis; - vertical-align: top; -} -.ql-snow .ql-tooltip a.ql-action::after { - border-right: 1px solid #ccc; - content: 'Edit'; - margin-left: 16px; - padding-right: 8px; -} -.ql-snow .ql-tooltip a.ql-remove::before { - content: 'Remove'; - margin-left: 8px; -} -.ql-snow .ql-tooltip a { - line-height: 26px; -} -.ql-snow .ql-tooltip.ql-editing a.ql-preview, -.ql-snow .ql-tooltip.ql-editing a.ql-remove { - display: none; -} -.ql-snow .ql-tooltip.ql-editing input[type=text] { - display: inline-block; -} -.ql-snow .ql-tooltip.ql-editing a.ql-action::after { - border-right: 0px; - content: 'Save'; - padding-right: 0px; -} -.ql-snow .ql-tooltip[data-mode=link]::before { - content: "Enter link:"; -} -.ql-snow .ql-tooltip[data-mode=formula]::before { - content: "Enter formula:"; -} -.ql-snow .ql-tooltip[data-mode=video]::before { - content: "Enter video:"; -} -.ql-snow a { - color: #06c; -} - -.ql-editor p { - margin-top: 1em; - margin-bottom: 0; -} - -.ql-editor p:first-child { - margin-top: 0 -} - -p.linebreak-true { - margin-top: 0; -} + .ql-container{box-sizing:border-box;font-family:Helvetica,Arial,sans-serif;font-size:13px;height:100%;margin:0;position:relative}.ql-container.ql-disabled .ql-tooltip{visibility:hidden}.ql-container:not(.ql-disabled) li[data-list=checked] > .ql-ui,.ql-container:not(.ql-disabled) li[data-list=unchecked] > .ql-ui{cursor:pointer}.ql-clipboard{left:-100000px;height:1px;overflow-y:hidden;position:absolute;top:50%}.ql-clipboard p{margin:0;padding:0}.ql-editor{box-sizing:border-box;counter-reset:list-0 list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;line-height:1.42;height:100%;outline:none;overflow-y:auto;padding:12px 15px;tab-size:4;-moz-tab-size:4;text-align:left;white-space:pre-wrap;word-wrap:break-word}.ql-editor > *{cursor:text}.ql-editor p,.ql-editor ol,.ql-editor pre,.ql-editor blockquote,.ql-editor h1,.ql-editor h2,.ql-editor h3,.ql-editor h4,.ql-editor h5,.ql-editor h6{margin:0;padding:0}@supports (counter-set:none){.ql-editor p,.ql-editor h1,.ql-editor h2,.ql-editor h3,.ql-editor h4,.ql-editor h5,.ql-editor h6{counter-set:list-0 list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor p,.ql-editor h1,.ql-editor h2,.ql-editor h3,.ql-editor h4,.ql-editor h5,.ql-editor h6{counter-reset:list-0 list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor table{border-collapse:collapse}.ql-editor td{border:1px solid #000;padding:2px 5px}.ql-editor ol{padding-left:1.5em}.ql-editor li{list-style-type:none;padding-left:1.5em;position:relative}.ql-editor li > .ql-ui:before{display:inline-block;margin-left:-1.5em;margin-right:.3em;text-align:right;white-space:nowrap;width:1.2em}.ql-editor li[data-list=checked] > .ql-ui,.ql-editor li[data-list=unchecked] > .ql-ui{color:#777}.ql-editor li[data-list=bullet] > .ql-ui:before{content:'\2022'}.ql-editor li[data-list=checked] > .ql-ui:before{content:'\2611'}.ql-editor li[data-list=unchecked] > .ql-ui:before{content:'\2610'}@supports (counter-set:none){.ql-editor li[data-list]{counter-set:list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list]{counter-reset:list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered]{counter-increment:list-0}.ql-editor li[data-list=ordered] > .ql-ui:before{content:counter(list-0, decimal) '. '}.ql-editor li[data-list=ordered].ql-indent-1{counter-increment:list-1}.ql-editor li[data-list=ordered].ql-indent-1 > .ql-ui:before{content:counter(list-1, lower-alpha) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-1{counter-set:list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-1{counter-reset:list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-2{counter-increment:list-2}.ql-editor li[data-list=ordered].ql-indent-2 > .ql-ui:before{content:counter(list-2, lower-roman) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-2{counter-set:list-3 list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-2{counter-reset:list-3 list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-3{counter-increment:list-3}.ql-editor li[data-list=ordered].ql-indent-3 > .ql-ui:before{content:counter(list-3, decimal) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-3{counter-set:list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-3{counter-reset:list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-4{counter-increment:list-4}.ql-editor li[data-list=ordered].ql-indent-4 > .ql-ui:before{content:counter(list-4, lower-alpha) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-4{counter-set:list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-4{counter-reset:list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-5{counter-increment:list-5}.ql-editor li[data-list=ordered].ql-indent-5 > .ql-ui:before{content:counter(list-5, lower-roman) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-5{counter-set:list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-5{counter-reset:list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-6{counter-increment:list-6}.ql-editor li[data-list=ordered].ql-indent-6 > .ql-ui:before{content:counter(list-6, decimal) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-6{counter-set:list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-6{counter-reset:list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-7{counter-increment:list-7}.ql-editor li[data-list=ordered].ql-indent-7 > .ql-ui:before{content:counter(list-7, lower-alpha) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-7{counter-set:list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-7{counter-reset:list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-8{counter-increment:list-8}.ql-editor li[data-list=ordered].ql-indent-8 > .ql-ui:before{content:counter(list-8, lower-roman) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-8{counter-set:list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-8{counter-reset:list-9}}.ql-editor li[data-list=ordered].ql-indent-9{counter-increment:list-9}.ql-editor li[data-list=ordered].ql-indent-9 > .ql-ui:before{content:counter(list-9, decimal) '. '}.ql-editor .ql-indent-1:not(.ql-direction-rtl){padding-left:3em}.ql-editor li.ql-indent-1:not(.ql-direction-rtl){padding-left:4.5em}.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right{padding-right:3em}.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right{padding-right:4.5em}.ql-editor .ql-indent-2:not(.ql-direction-rtl){padding-left:6em}.ql-editor li.ql-indent-2:not(.ql-direction-rtl){padding-left:7.5em}.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right{padding-right:6em}.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right{padding-right:7.5em}.ql-editor .ql-indent-3:not(.ql-direction-rtl){padding-left:9em}.ql-editor li.ql-indent-3:not(.ql-direction-rtl){padding-left:10.5em}.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right{padding-right:9em}.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right{padding-right:10.5em}.ql-editor .ql-indent-4:not(.ql-direction-rtl){padding-left:12em}.ql-editor li.ql-indent-4:not(.ql-direction-rtl){padding-left:13.5em}.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right{padding-right:12em}.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right{padding-right:13.5em}.ql-editor .ql-indent-5:not(.ql-direction-rtl){padding-left:15em}.ql-editor li.ql-indent-5:not(.ql-direction-rtl){padding-left:16.5em}.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right{padding-right:15em}.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right{padding-right:16.5em}.ql-editor .ql-indent-6:not(.ql-direction-rtl){padding-left:18em}.ql-editor li.ql-indent-6:not(.ql-direction-rtl){padding-left:19.5em}.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right{padding-right:18em}.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right{padding-right:19.5em}.ql-editor .ql-indent-7:not(.ql-direction-rtl){padding-left:21em}.ql-editor li.ql-indent-7:not(.ql-direction-rtl){padding-left:22.5em}.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right{padding-right:21em}.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right{padding-right:22.5em}.ql-editor .ql-indent-8:not(.ql-direction-rtl){padding-left:24em}.ql-editor li.ql-indent-8:not(.ql-direction-rtl){padding-left:25.5em}.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right{padding-right:24em}.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right{padding-right:25.5em}.ql-editor .ql-indent-9:not(.ql-direction-rtl){padding-left:27em}.ql-editor li.ql-indent-9:not(.ql-direction-rtl){padding-left:28.5em}.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right{padding-right:27em}.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right{padding-right:28.5em}.ql-editor li.ql-direction-rtl{padding-right:1.5em}.ql-editor li.ql-direction-rtl > .ql-ui:before{margin-left:.3em;margin-right:-1.5em;text-align:left}.ql-editor table{table-layout:fixed;width:100%}.ql-editor table td{outline:none}.ql-editor .ql-code-block-container{font-family:monospace}.ql-editor .ql-video{display:block;max-width:100%}.ql-editor .ql-video.ql-align-center{margin:0 auto}.ql-editor .ql-video.ql-align-right{margin:0 0 0 auto}.ql-editor .ql-bg-black{background-color:#000}.ql-editor .ql-bg-red{background-color:#e60000}.ql-editor .ql-bg-orange{background-color:#f90}.ql-editor .ql-bg-yellow{background-color:#ff0}.ql-editor .ql-bg-green{background-color:#008a00}.ql-editor .ql-bg-blue{background-color:#06c}.ql-editor .ql-bg-purple{background-color:#93f}.ql-editor .ql-color-white{color:#fff}.ql-editor .ql-color-red{color:#e60000}.ql-editor .ql-color-orange{color:#f90}.ql-editor .ql-color-yellow{color:#ff0}.ql-editor .ql-color-green{color:#008a00}.ql-editor .ql-color-blue{color:#06c}.ql-editor .ql-color-purple{color:#93f}.ql-editor .ql-font-serif{font-family:Georgia,Times New Roman,serif}.ql-editor .ql-font-monospace{font-family:Monaco,Courier New,monospace}.ql-editor .ql-size-small{font-size:.75em}.ql-editor .ql-size-large{font-size:1.5em}.ql-editor .ql-size-huge{font-size:2.5em}.ql-editor .ql-direction-rtl{direction:rtl;text-align:inherit}.ql-editor .ql-align-center{text-align:center}.ql-editor .ql-align-justify{text-align:justify}.ql-editor .ql-align-right{text-align:right}.ql-editor .ql-ui{position:absolute}.ql-editor.ql-blank::before{color:rgba(0,0,0,0.6);content:attr(data-placeholder);font-style:italic;left:15px;pointer-events:none;position:absolute;right:15px}.ql-snow.ql-toolbar:after,.ql-snow .ql-toolbar:after{clear:both;content:'';display:table}.ql-snow.ql-toolbar button,.ql-snow .ql-toolbar button{background:none;border:none;cursor:pointer;display:inline-block;float:left;height:24px;padding:3px 5px;width:28px}.ql-snow.ql-toolbar button svg,.ql-snow .ql-toolbar button svg{float:left;height:100%}.ql-snow.ql-toolbar button:active:hover,.ql-snow .ql-toolbar button:active:hover{outline:none}.ql-snow.ql-toolbar input.ql-image[type=file],.ql-snow .ql-toolbar input.ql-image[type=file]{display:none}.ql-snow.ql-toolbar button:hover,.ql-snow .ql-toolbar button:hover,.ql-snow.ql-toolbar button:focus,.ql-snow .ql-toolbar button:focus,.ql-snow.ql-toolbar button.ql-active,.ql-snow .ql-toolbar button.ql-active,.ql-snow.ql-toolbar .ql-picker-label:hover,.ql-snow .ql-toolbar .ql-picker-label:hover,.ql-snow.ql-toolbar .ql-picker-label.ql-active,.ql-snow .ql-toolbar .ql-picker-label.ql-active,.ql-snow.ql-toolbar .ql-picker-item:hover,.ql-snow .ql-toolbar .ql-picker-item:hover,.ql-snow.ql-toolbar .ql-picker-item.ql-selected,.ql-snow .ql-toolbar .ql-picker-item.ql-selected{color:#06c}.ql-snow.ql-toolbar button:hover .ql-fill,.ql-snow .ql-toolbar button:hover .ql-fill,.ql-snow.ql-toolbar button:focus .ql-fill,.ql-snow .ql-toolbar button:focus .ql-fill,.ql-snow.ql-toolbar button.ql-active .ql-fill,.ql-snow .ql-toolbar button.ql-active .ql-fill,.ql-snow.ql-toolbar .ql-picker-label:hover .ql-fill,.ql-snow .ql-toolbar .ql-picker-label:hover .ql-fill,.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-fill,.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-fill,.ql-snow.ql-toolbar .ql-picker-item:hover .ql-fill,.ql-snow .ql-toolbar .ql-picker-item:hover .ql-fill,.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-fill,.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-fill,.ql-snow.ql-toolbar button:hover .ql-stroke.ql-fill,.ql-snow .ql-toolbar button:hover .ql-stroke.ql-fill,.ql-snow.ql-toolbar button:focus .ql-stroke.ql-fill,.ql-snow .ql-toolbar button:focus .ql-stroke.ql-fill,.ql-snow.ql-toolbar button.ql-active .ql-stroke.ql-fill,.ql-snow .ql-toolbar button.ql-active .ql-stroke.ql-fill,.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill,.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill,.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill,.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill,.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill,.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill,.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill,.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill{fill:#06c}.ql-snow.ql-toolbar button:hover .ql-stroke,.ql-snow .ql-toolbar button:hover .ql-stroke,.ql-snow.ql-toolbar button:focus .ql-stroke,.ql-snow .ql-toolbar button:focus .ql-stroke,.ql-snow.ql-toolbar button.ql-active .ql-stroke,.ql-snow .ql-toolbar button.ql-active .ql-stroke,.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke,.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke,.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke,.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke,.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke,.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke,.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke,.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke,.ql-snow.ql-toolbar button:hover .ql-stroke-miter,.ql-snow .ql-toolbar button:hover .ql-stroke-miter,.ql-snow.ql-toolbar button:focus .ql-stroke-miter,.ql-snow .ql-toolbar button:focus .ql-stroke-miter,.ql-snow.ql-toolbar button.ql-active .ql-stroke-miter,.ql-snow .ql-toolbar button.ql-active .ql-stroke-miter,.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke-miter,.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke-miter,.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter,.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter,.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke-miter,.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke-miter,.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter,.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter{stroke:#06c}@media (pointer:coarse){.ql-snow.ql-toolbar button:hover:not(.ql-active),.ql-snow .ql-toolbar button:hover:not(.ql-active){color:#444}.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-fill,.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-fill,.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill,.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill{fill:#444}.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke,.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke,.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter,.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter{stroke:#444}}.ql-snow{box-sizing:border-box}.ql-snow *{box-sizing:border-box}.ql-snow .ql-hidden{display:none}.ql-snow .ql-out-bottom,.ql-snow .ql-out-top{visibility:hidden}.ql-snow .ql-tooltip{position:absolute;transform:translateY(10px)}.ql-snow .ql-tooltip a{cursor:pointer;text-decoration:none}.ql-snow .ql-tooltip.ql-flip{transform:translateY(-10px)}.ql-snow .ql-formats{display:inline-block;vertical-align:middle}.ql-snow .ql-formats:after{clear:both;content:'';display:table}.ql-snow .ql-stroke{fill:none;stroke:#444;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}.ql-snow .ql-stroke-miter{fill:none;stroke:#444;stroke-miterlimit:10;stroke-width:2}.ql-snow .ql-fill,.ql-snow .ql-stroke.ql-fill{fill:#444}.ql-snow .ql-empty{fill:none}.ql-snow .ql-even{fill-rule:evenodd}.ql-snow .ql-thin,.ql-snow .ql-stroke.ql-thin{stroke-width:1}.ql-snow .ql-transparent{opacity:.4}.ql-snow .ql-direction svg:last-child{display:none}.ql-snow .ql-direction.ql-active svg:last-child{display:inline}.ql-snow .ql-direction.ql-active svg:first-child{display:none}.ql-snow .ql-editor h1{font-size:2em}.ql-snow .ql-editor h2{font-size:1.5em}.ql-snow .ql-editor h3{font-size:1.17em}.ql-snow .ql-editor h4{font-size:1em}.ql-snow .ql-editor h5{font-size:.83em}.ql-snow .ql-editor h6{font-size:.67em}.ql-snow .ql-editor a{text-decoration:underline}.ql-snow .ql-editor blockquote{border-left:4px solid #ccc;margin-bottom:5px;margin-top:5px;padding-left:16px}.ql-snow .ql-editor code,.ql-snow .ql-editor .ql-code-block-container{background-color:#f0f0f0;border-radius:3px}.ql-snow .ql-editor .ql-code-block-container{margin-bottom:5px;margin-top:5px;padding:5px 10px}.ql-snow .ql-editor code{font-size:85%;padding:2px 4px}.ql-snow .ql-editor .ql-code-block-container{background-color:#23241f;color:#f8f8f2;overflow:visible}.ql-snow .ql-editor img{max-width:100%}.ql-snow .ql-picker{color:#444;display:inline-block;float:left;font-size:14px;font-weight:500;height:24px;position:relative;vertical-align:middle}.ql-snow .ql-picker-label{cursor:pointer;display:inline-block;height:100%;padding-left:8px;padding-right:2px;position:relative;width:100%}.ql-snow .ql-picker-label::before{display:inline-block;line-height:22px}.ql-snow .ql-picker-options{background-color:#fff;display:none;min-width:100%;padding:4px 8px;position:absolute;white-space:nowrap}.ql-snow .ql-picker-options .ql-picker-item{cursor:pointer;display:block;padding-bottom:5px;padding-top:5px}.ql-snow .ql-picker.ql-expanded .ql-picker-label{color:#ccc;z-index:2}.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-fill{fill:#ccc}.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-stroke{stroke:#ccc}.ql-snow .ql-picker.ql-expanded .ql-picker-options{display:block;margin-top:-1px;top:100%;z-index:1}.ql-snow .ql-color-picker,.ql-snow .ql-icon-picker{width:28px}.ql-snow .ql-color-picker .ql-picker-label,.ql-snow .ql-icon-picker .ql-picker-label{padding:2px 4px}.ql-snow .ql-color-picker .ql-picker-label svg,.ql-snow .ql-icon-picker .ql-picker-label svg{right:4px}.ql-snow .ql-icon-picker .ql-picker-options{padding:4px 0}.ql-snow .ql-icon-picker .ql-picker-item{height:24px;width:24px;padding:2px 4px}.ql-snow .ql-color-picker .ql-picker-options{padding:3px 5px;width:152px}.ql-snow .ql-color-picker .ql-picker-item{border:1px solid transparent;float:left;height:16px;margin:2px;padding:0;width:16px}.ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg{position:absolute;margin-top:-9px;right:0;top:50%;width:18px}.ql-snow .ql-picker.ql-header .ql-picker-label[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-font .ql-picker-label[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-size .ql-picker-label[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-label]:not([data-label=''])::before{content:attr(data-label)}.ql-snow .ql-picker.ql-header{width:98px}.ql-snow .ql-picker.ql-header .ql-picker-label::before,.ql-snow .ql-picker.ql-header .ql-picker-item::before{content:'Normal'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before{content:'Heading 1'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before{content:'Heading 2'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before{content:'Heading 3'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before{content:'Heading 4'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before{content:'Heading 5'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before{content:'Heading 6'}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before{font-size:2em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before{font-size:1.5em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before{font-size:1.17em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before{font-size:1em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before{font-size:.83em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before{font-size:.67em}.ql-snow .ql-picker.ql-font{width:108px}.ql-snow .ql-picker.ql-font .ql-picker-label::before,.ql-snow .ql-picker.ql-font .ql-picker-item::before{content:'Sans Serif'}.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before{content:'Serif'}.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before{content:'Monospace'}.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before{font-family:Georgia,Times New Roman,serif}.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before{font-family:Monaco,Courier New,monospace}.ql-snow .ql-picker.ql-size{width:98px}.ql-snow .ql-picker.ql-size .ql-picker-label::before,.ql-snow .ql-picker.ql-size .ql-picker-item::before{content:'Normal'}.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before{content:'Small'}.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before{content:'Large'}.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before{content:'Huge'}.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before{font-size:10px}.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before{font-size:18px}.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before{font-size:32px}.ql-snow .ql-color-picker.ql-background .ql-picker-item{background-color:#fff}.ql-snow .ql-color-picker.ql-color .ql-picker-item{background-color:#000}.ql-code-block-container{position:relative}.ql-code-block-container .ql-ui{right:5px;top:5px}.ql-toolbar.ql-snow{border:1px solid #ccc;box-sizing:border-box;font-family:'Helvetica Neue','Helvetica','Arial',sans-serif;padding:8px}.ql-toolbar.ql-snow .ql-formats{margin-right:15px}.ql-toolbar.ql-snow .ql-picker-label{border:1px solid transparent}.ql-toolbar.ql-snow .ql-picker-options{border:1px solid transparent;box-shadow:rgba(0,0,0,0.2) 0 2px 8px}.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label{border-color:#ccc}.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options{border-color:#ccc}.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item.ql-selected,.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item:hover{border-color:#000}.ql-toolbar.ql-snow + .ql-container.ql-snow{border-top:0}.ql-snow .ql-tooltip{background-color:#fff;border:1px solid #ccc;box-shadow:0 0 5px #ddd;color:#444;padding:5px 12px;white-space:nowrap}.ql-snow .ql-tooltip::before{content:"Visit URL:";line-height:26px;margin-right:8px}.ql-snow .ql-tooltip input[type=text]{display:none;border:1px solid #ccc;font-size:13px;height:26px;margin:0;padding:3px 5px;width:170px}.ql-snow .ql-tooltip a.ql-preview{display:inline-block;max-width:200px;overflow-x:hidden;text-overflow:ellipsis;vertical-align:top}.ql-snow .ql-tooltip a.ql-action::after{border-right:1px solid #ccc;content:'Edit';margin-left:16px;padding-right:8px}.ql-snow .ql-tooltip a.ql-remove::before{content:'Remove';margin-left:8px}.ql-snow .ql-tooltip a{line-height:26px}.ql-snow .ql-tooltip.ql-editing a.ql-preview,.ql-snow .ql-tooltip.ql-editing a.ql-remove{display:none}.ql-snow .ql-tooltip.ql-editing input[type=text]{display:inline-block}.ql-snow .ql-tooltip.ql-editing a.ql-action::after{border-right:0;content:'Save';padding-right:0}.ql-snow .ql-tooltip[data-mode=link]::before{content:"Enter link:"}.ql-snow .ql-tooltip[data-mode=formula]::before{content:"Enter formula:"}.ql-snow .ql-tooltip[data-mode=video]::before{content:"Enter video:"}.ql-snow a{color:#06c}.ql-container.ql-snow{border:1px solid #ccc} diff --git a/Desktop/html/js/highlight-r.min.js b/Desktop/html/js/highlight-r.min.js index 0af724cca7..b330b3431b 100644 --- a/Desktop/html/js/highlight-r.min.js +++ b/Desktop/html/js/highlight-r.min.js @@ -1,4 +1,4 @@ -/*! `r` grammar compiled for Highlight.js 11.7.0 */ +/*! `r` grammar compiled for Highlight.js 11.9.0 */ (()=>{var e=(()=>{"use strict";return e=>{ const a=e.regex,n=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,i=a.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),s=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,t=a.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/) ;return{name:"R",keywords:{$pattern:n, @@ -23,5 +23,4 @@ 2:"number"},match:[/[^a-zA-Z0-9._]|^/,i]}]},{scope:{3:"operator"}, match:[n,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:s},{ match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:t},{begin:"`",end:"`", - contains:[{begin:/\\./}]}]}}})();hljs.registerLanguage("r",e)})(); - \ No newline at end of file + contains:[{begin:/\\./}]}]}}})();hljs.registerLanguage("r",e)})(); \ No newline at end of file diff --git a/Desktop/html/js/highlight.min.js b/Desktop/html/js/highlight.min.js index 3a722bfcb1..f43ba9aa97 100644 --- a/Desktop/html/js/highlight.min.js +++ b/Desktop/html/js/highlight.min.js @@ -1,33 +1,33 @@ /*! - Highlight.js v11.7.0 (git: 82688fad18) - (c) 2006-2022 undefined and other contributors + Highlight.js v11.9.0 (git: f47103d4f1) + (c) 2006-2023 undefined and other contributors License: BSD-3-Clause */ - var hljs=function(){"use strict";var e={exports:{}};function n(e){ - return e instanceof Map?e.clear=e.delete=e.set=()=>{ - throw Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=()=>{ + var hljs=function(){"use strict";function e(n){ + return n instanceof Map?n.clear=n.delete=n.set=()=>{ + throw Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=()=>{ throw Error("set is read-only") - }),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((t=>{var a=e[t] - ;"object"!=typeof a||Object.isFrozen(a)||n(a)})),e} - e.exports=n,e.exports.default=n;class t{constructor(e){ + }),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((t=>{ + const a=n[t],i=typeof a;"object"!==i&&"function"!==i||Object.isFrozen(a)||e(a) + })),n}class n{constructor(e){ void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} - ignoreMatch(){this.isMatchIgnored=!0}}function a(e){ + ignoreMatch(){this.isMatchIgnored=!0}}function t(e){ return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'") - }function i(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n] - ;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t} - const r=e=>!!e.scope||e.sublanguage&&e.language;class s{constructor(e,n){ + }function a(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n] + ;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t}const i=e=>!!e.scope + ;class r{constructor(e,n){ this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){ - this.buffer+=a(e)}openNode(e){if(!r(e))return;let n="" - ;n=e.sublanguage?"language-"+e.language:((e,{prefix:n})=>{if(e.includes(".")){ - const t=e.split(".") + this.buffer+=t(e)}openNode(e){if(!i(e))return;const n=((e,{prefix:n})=>{ + if(e.startsWith("language:"))return e.replace("language:","language-") + ;if(e.includes(".")){const t=e.split(".") ;return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ") - }return`${n}${e}`})(e.scope,{prefix:this.classPrefix}),this.span(n)} - closeNode(e){r(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ - this.buffer+=``}}const o=(e={})=>{const n={children:[]} - ;return Object.assign(n,e),n};class l{constructor(){ - this.rootNode=o(),this.stack=[this.rootNode]}get top(){ + }return`${n}${e}`})(e.scope,{prefix:this.classPrefix});this.span(n)} + closeNode(e){i(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ + this.buffer+=``}}const s=(e={})=>{const n={children:[]} + ;return Object.assign(n,e),n};class o{constructor(){ + this.rootNode=s(),this.stack=[this.rootNode]}get top(){ return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ - this.top.children.push(e)}openNode(e){const n=o({scope:e}) + this.top.children.push(e)}openNode(e){const n=s({scope:e}) ;this.add(n),this.stack.push(n)}closeNode(){ if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} @@ -35,104 +35,105 @@ return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n), n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){ "string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ - l._collapse(e)})))}}class c extends l{constructor(e){super(),this.options=e} - addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())} - addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root - ;t.sublanguage=!0,t.language=n,this.add(t)}toHTML(){ - return new s(this,this.options).value()}finalize(){return!0}}function d(e){ - return e?"string"==typeof e?e:e.source:null}function g(e){return m("(?=",e,")")} - function u(e){return m("(?:",e,")*")}function b(e){return m("(?:",e,")?")} - function m(...e){return e.map((e=>d(e))).join("")}function p(...e){const n=(e=>{ + o._collapse(e)})))}}class l extends o{constructor(e){super(),this.options=e} + addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){ + this.closeNode()}__addSublanguage(e,n){const t=e.root + ;n&&(t.scope="language:"+n),this.add(t)}toHTML(){ + return new r(this,this.options).value()}finalize(){ + return this.closeAllNodes(),!0}}function c(e){ + return e?"string"==typeof e?e:e.source:null}function d(e){return b("(?=",e,")")} + function g(e){return b("(?:",e,")*")}function u(e){return b("(?:",e,")?")} + function b(...e){return e.map((e=>c(e))).join("")}function m(...e){const n=(e=>{ const n=e[e.length-1] ;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{} - })(e);return"("+(n.capture?"":"?:")+e.map((e=>d(e))).join("|")+")"} - function _(e){return RegExp(e.toString()+"|").exec("").length-1} - const h=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ - ;function f(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t - ;let a=d(e),i="";for(;a.length>0;){const e=h.exec(a);if(!e){i+=a;break} + })(e);return"("+(n.capture?"":"?:")+e.map((e=>c(e))).join("|")+")"} + function p(e){return RegExp(e.toString()+"|").exec("").length-1} + const _=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ + ;function h(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t + ;let a=c(e),i="";for(;a.length>0;){const e=_.exec(a);if(!e){i+=a;break} i+=a.substring(0,e.index), a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0], "("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)} - const E="[a-zA-Z]\\w*",y="[a-zA-Z_]\\w*",w="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",v="\\b(0b[01]+)",O={ - begin:"\\\\[\\s\\S]",relevance:0},k={scope:"string",begin:"'",end:"'", - illegal:"\\n",contains:[O]},x={scope:"string",begin:'"',end:'"',illegal:"\\n", - contains:[O]},M=(e,n,t={})=>{const a=i({scope:"comment",begin:e,end:n, - contains:[]},t);a.contains.push({scope:"doctag", + const f="[a-zA-Z]\\w*",E="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w="\\b(0b[01]+)",v={ + begin:"\\\\[\\s\\S]",relevance:0},O={scope:"string",begin:"'",end:"'", + illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n", + contains:[v]},x=(e,n,t={})=>{const i=a({scope:"comment",begin:e,end:n, + contains:[]},t);i.contains.push({scope:"doctag", begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) - ;const r=p("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) - ;return a.contains.push({begin:m(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),a - },S=M("//","$"),A=M("/\\*","\\*/"),C=M("#","$");var T=Object.freeze({ - __proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:E,UNDERSCORE_IDENT_RE:y, - NUMBER_RE:w,C_NUMBER_RE:N,BINARY_NUMBER_RE:v, + ;const r=m("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) + ;return i.contains.push({begin:b(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i + },M=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$");var C=Object.freeze({ + __proto__:null,APOS_STRING_MODE:O,BACKSLASH_ESCAPE:v,BINARY_NUMBER_MODE:{ + scope:"number",begin:w,relevance:0},BINARY_NUMBER_RE:w,COMMENT:x, + C_BLOCK_COMMENT_MODE:S,C_LINE_COMMENT_MODE:M,C_NUMBER_MODE:{scope:"number", + begin:N,relevance:0},C_NUMBER_RE:N,END_SAME_AS_BEGIN:e=>Object.assign(e,{ + "on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{ + n.data._beginMatch!==e[1]&&n.ignoreMatch()}}),HASH_COMMENT_MODE:A,IDENT_RE:f, + MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+E,relevance:0}, + NUMBER_MODE:{scope:"number",begin:y,relevance:0},NUMBER_RE:y, + PHRASAL_WORDS_MODE:{ + begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ + },QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/, + end:/\/[gimuy]*/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]}, RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", SHEBANG:(e={})=>{const n=/^#![ ]*\// - ;return e.binary&&(e.begin=m(n,/.*\b/,e.binary,/\b.*/)),i({scope:"meta",begin:n, + ;return e.binary&&(e.begin=b(n,/.*\b/,e.binary,/\b.*/)),a({scope:"meta",begin:n, end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)}, - BACKSLASH_ESCAPE:O,APOS_STRING_MODE:k,QUOTE_STRING_MODE:x,PHRASAL_WORDS_MODE:{ - begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ - },COMMENT:M,C_LINE_COMMENT_MODE:S,C_BLOCK_COMMENT_MODE:A,HASH_COMMENT_MODE:C, - NUMBER_MODE:{scope:"number",begin:w,relevance:0},C_NUMBER_MODE:{scope:"number", - begin:N,relevance:0},BINARY_NUMBER_MODE:{scope:"number",begin:v,relevance:0}, - REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{scope:"regexp",begin:/\//, - end:/\/[gimuy]*/,illegal:/\n/,contains:[O,{begin:/\[/,end:/\]/,relevance:0, - contains:[O]}]}]},TITLE_MODE:{scope:"title",begin:E,relevance:0}, - UNDERSCORE_TITLE_MODE:{scope:"title",begin:y,relevance:0},METHOD_GUARD:{ - begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},END_SAME_AS_BEGIN:e=>Object.assign(e,{ - "on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{ - n.data._beginMatch!==e[1]&&n.ignoreMatch()}})});function R(e,n){ - "."===e.input[e.index-1]&&n.ignoreMatch()}function D(e,n){ - void 0!==e.className&&(e.scope=e.className,delete e.className)}function I(e,n){ + TITLE_MODE:{scope:"title",begin:f,relevance:0},UNDERSCORE_IDENT_RE:E, + UNDERSCORE_TITLE_MODE:{scope:"title",begin:E,relevance:0}});function T(e,n){ + "."===e.input[e.index-1]&&n.ignoreMatch()}function R(e,n){ + void 0!==e.className&&(e.scope=e.className,delete e.className)}function D(e,n){ n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", - e.__beforeBegin=R,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, - void 0===e.relevance&&(e.relevance=0))}function L(e,n){ - Array.isArray(e.illegal)&&(e.illegal=p(...e.illegal))}function B(e,n){ + e.__beforeBegin=T,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, + void 0===e.relevance&&(e.relevance=0))}function I(e,n){ + Array.isArray(e.illegal)&&(e.illegal=m(...e.illegal))}function L(e,n){ if(e.match){ if(e.begin||e.end)throw Error("begin & end are not supported with match") - ;e.begin=e.match,delete e.match}}function $(e,n){ - void 0===e.relevance&&(e.relevance=1)}const z=(e,n)=>{if(!e.beforeMatch)return + ;e.begin=e.match,delete e.match}}function B(e,n){ + void 0===e.relevance&&(e.relevance=1)}const $=(e,n)=>{if(!e.beforeMatch)return ;if(e.starts)throw Error("beforeMatch cannot be used with starts") ;const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n] - })),e.keywords=t.keywords,e.begin=m(t.beforeMatch,g(t.begin)),e.starts={ + })),e.keywords=t.keywords,e.begin=b(t.beforeMatch,d(t.begin)),e.starts={ relevance:0,contains:[Object.assign(t,{endsParent:!0})] },e.relevance=0,delete t.beforeMatch - },F=["of","and","for","in","not","or","if","then","parent","list","value"] - ;function U(e,n,t="keyword"){const a=Object.create(null) + },z=["of","and","for","in","not","or","if","then","parent","list","value"],F="keyword" + ;function U(e,n,t=F){const a=Object.create(null) ;return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{ Object.assign(a,U(e[t],n,t))})),a;function i(e,t){ n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|") ;a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){ - return n?Number(n):(e=>F.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{ + return n?Number(n):(e=>z.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{ console.error(e)},H=(e,...n)=>{console.log("WARN: "+e,...n)},q=(e,n)=>{ P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0) - },Z=Error();function G(e,n,{key:t}){let a=0;const i=e[t],r={},s={} - ;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=_(n[e-1]) + },G=Error();function Z(e,n,{key:t}){let a=0;const i=e[t],r={},s={} + ;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=p(n[e-1]) ;e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{ e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ _wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope }),(e=>{if(Array.isArray(e.begin)){ if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), - Z + G ;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"), - Z;G(e,e.begin,{key:"beginScope"}),e.begin=f(e.begin,{joinWith:""})}})(e),(e=>{ + G;Z(e,e.begin,{key:"beginScope"}),e.begin=h(e.begin,{joinWith:""})}})(e),(e=>{ if(Array.isArray(e.end)){ if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"), - Z + G ;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"), - Z;G(e,e.end,{key:"endScope"}),e.end=f(e.end,{joinWith:""})}})(e)}function Q(e){ + G;Z(e,e.end,{key:"endScope"}),e.end=h(e.end,{joinWith:""})}})(e)}function Q(e){ function n(n,t){ - return RegExp(d(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":"")) + return RegExp(c(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":"")) }class t{constructor(){ this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} addRule(e,n){ n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]), - this.matchAt+=_(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) - ;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(f(e,{joinWith:"|" + this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) + ;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(h(e,{joinWith:"|" }),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex ;const n=this.matcherRe.exec(e);if(!n)return null ;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t] - ;return n.splice(0,t),Object.assign(n,a)}}class a{constructor(){ + ;return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){ this.rules=[],this.multiRegexes=[], this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t @@ -148,148 +149,150 @@ this.regexIndex===this.count&&this.considerAll()),t}} if(e.compilerExtensions||(e.compilerExtensions=[]), e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") - ;return e.classNameAliases=i(e.classNameAliases||{}),function t(r,s){const o=r + ;return e.classNameAliases=a(e.classNameAliases||{}),function t(r,s){const o=r ;if(r.isCompiled)return o - ;[D,B,W,z].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))), - r.__beforeBegin=null,[I,L,$].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null + ;[R,L,W,$].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))), + r.__beforeBegin=null,[D,I,B].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null ;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords), l=r.keywords.$pattern, delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)), o.keywordPatternRe=n(l,!0), s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/), r.end&&(o.endRe=n(o.end)), - o.terminatorEnd=d(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)), + o.terminatorEnd=c(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)), r.illegal&&(o.illegalRe=n(r.illegal)), - r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>i(e,{ - variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?i(e,{ - starts:e.starts?i(e.starts):null - }):Object.isFrozen(e)?i(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o) - })),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new a + r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>a(e,{ + variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?a(e,{ + starts:e.starts?a(e.starts):null + }):Object.isFrozen(e)?a(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o) + })),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new i ;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin" }))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end" }),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){ return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{ constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}} - const J=a,Y=i,ee=Symbol("nomatch");var ne=(n=>{ + const J=t,Y=a,ee=Symbol("nomatch"),ne=t=>{ const a=Object.create(null),i=Object.create(null),r=[];let s=!0 - ;const o="Could not find the language '{}', did you forget to load/include a language module?",l={ - disableAutodetect:!0,name:"Plain text",contains:[]};let d={ + ;const o="Could not find the language '{}', did you forget to load/include a language module?",c={ + disableAutodetect:!0,name:"Plain text",contains:[]};let p={ ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", - cssSelector:"pre code",languages:null,__emitter:c};function _(e){ - return d.noHighlightRe.test(e)}function h(e,n,t){let a="",i="" + cssSelector:"pre code",languages:null,__emitter:l};function _(e){ + return p.noHighlightRe.test(e)}function h(e,n,t){let a="",i="" ;"object"==typeof n?(a=e, t=n.ignoreIllegals,i=n.language):(q("10.7.0","highlight(lang, code, ...args) has been deprecated."), q("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r) ;const s=r.result?r.result:f(r.language,r.code,t) - ;return s.code=r.code,x("after:highlight",s),s}function f(e,n,i,r){ - const l=Object.create(null);function c(){if(!k.keywords)return void M.addText(S) - ;let e=0;k.keywordPatternRe.lastIndex=0;let n=k.keywordPatternRe.exec(S),t="" - ;for(;n;){t+=S.substring(e,n.index) - ;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,k.keywords[a]);if(r){ + ;return s.code=r.code,x("after:highlight",s),s}function f(e,t,i,r){ + const l=Object.create(null);function c(){if(!x.keywords)return void S.addText(A) + ;let e=0;x.keywordPatternRe.lastIndex=0;let n=x.keywordPatternRe.exec(A),t="" + ;for(;n;){t+=A.substring(e,n.index) + ;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,x.keywords[a]);if(r){ const[e,a]=r - ;if(M.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(A+=a),e.startsWith("_"))t+=n[0];else{ - const t=w.classNameAliases[e]||e;M.addKeyword(n[0],t)}}else t+=n[0] - ;e=k.keywordPatternRe.lastIndex,n=k.keywordPatternRe.exec(S)}var a - ;t+=S.substring(e),M.addText(t)}function g(){null!=k.subLanguage?(()=>{ - if(""===S)return;let e=null;if("string"==typeof k.subLanguage){ - if(!a[k.subLanguage])return void M.addText(S) - ;e=f(k.subLanguage,S,!0,x[k.subLanguage]),x[k.subLanguage]=e._top - }else e=E(S,k.subLanguage.length?k.subLanguage:null) - ;k.relevance>0&&(A+=e.relevance),M.addSublanguage(e._emitter,e.language) - })():c(),S=""}function u(e,n){let t=1;const a=n.length-1;for(;t<=a;){ - if(!e._emit[t]){t++;continue}const a=w.classNameAliases[e[t]]||e[t],i=n[t] - ;a?M.addKeyword(i,a):(S=i,c(),S=""),t++}}function b(e,n){ - return e.scope&&"string"==typeof e.scope&&M.openNode(w.classNameAliases[e.scope]||e.scope), - e.beginScope&&(e.beginScope._wrap?(M.addKeyword(S,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), - S=""):e.beginScope._multi&&(u(e.beginScope,n),S="")),k=Object.create(e,{parent:{ - value:k}}),k}function m(e,n,a){let i=((e,n)=>{const t=e&&e.exec(n) - ;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new t(e) - ;e["on:end"](n,a),a.isMatchIgnored&&(i=!1)}if(i){ + ;if(S.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(C+=a),e.startsWith("_"))t+=n[0];else{ + const t=w.classNameAliases[e]||e;g(n[0],t)}}else t+=n[0] + ;e=x.keywordPatternRe.lastIndex,n=x.keywordPatternRe.exec(A)}var a + ;t+=A.substring(e),S.addText(t)}function d(){null!=x.subLanguage?(()=>{ + if(""===A)return;let e=null;if("string"==typeof x.subLanguage){ + if(!a[x.subLanguage])return void S.addText(A) + ;e=f(x.subLanguage,A,!0,M[x.subLanguage]),M[x.subLanguage]=e._top + }else e=E(A,x.subLanguage.length?x.subLanguage:null) + ;x.relevance>0&&(C+=e.relevance),S.__addSublanguage(e._emitter,e.language) + })():c(),A=""}function g(e,n){ + ""!==e&&(S.startScope(n),S.addText(e),S.endScope())}function u(e,n){let t=1 + ;const a=n.length-1;for(;t<=a;){if(!e._emit[t]){t++;continue} + const a=w.classNameAliases[e[t]]||e[t],i=n[t];a?g(i,a):(A=i,c(),A=""),t++}} + function b(e,n){ + return e.scope&&"string"==typeof e.scope&&S.openNode(w.classNameAliases[e.scope]||e.scope), + e.beginScope&&(e.beginScope._wrap?(g(A,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), + A=""):e.beginScope._multi&&(u(e.beginScope,n),A="")),x=Object.create(e,{parent:{ + value:x}}),x}function m(e,t,a){let i=((e,n)=>{const t=e&&e.exec(n) + ;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new n(e) + ;e["on:end"](t,a),a.isMatchIgnored&&(i=!1)}if(i){ for(;e.endsParent&&e.parent;)e=e.parent;return e}} - if(e.endsWithParent)return m(e.parent,n,a)}function p(e){ - return 0===k.matcher.regexIndex?(S+=e[0],1):(R=!0,0)}function _(e){ - const t=e[0],a=n.substring(e.index),i=m(k,e,a);if(!i)return ee;const r=k - ;k.endScope&&k.endScope._wrap?(g(), - M.addKeyword(t,k.endScope._wrap)):k.endScope&&k.endScope._multi?(g(), - u(k.endScope,e)):r.skip?S+=t:(r.returnEnd||r.excludeEnd||(S+=t), - g(),r.excludeEnd&&(S=t));do{ - k.scope&&M.closeNode(),k.skip||k.subLanguage||(A+=k.relevance),k=k.parent - }while(k!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:t.length} - let h={};function y(a,r){const o=r&&r[0];if(S+=a,null==o)return g(),0 - ;if("begin"===h.type&&"end"===r.type&&h.index===r.index&&""===o){ - if(S+=n.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`) - ;throw n.languageName=e,n.badRule=h.rule,n}return 1} - if(h=r,"begin"===r.type)return(e=>{ - const n=e[0],a=e.rule,i=new t(a),r=[a.__beforeBegin,a["on:begin"]] - ;for(const t of r)if(t&&(t(e,i),i.isMatchIgnored))return p(n) - ;return a.skip?S+=n:(a.excludeBegin&&(S+=n), - g(),a.returnBegin||a.excludeBegin||(S=n)),b(a,e),a.returnBegin?0:n.length})(r) + if(e.endsWithParent)return m(e.parent,t,a)}function _(e){ + return 0===x.matcher.regexIndex?(A+=e[0],1):(D=!0,0)}function h(e){ + const n=e[0],a=t.substring(e.index),i=m(x,e,a);if(!i)return ee;const r=x + ;x.endScope&&x.endScope._wrap?(d(), + g(n,x.endScope._wrap)):x.endScope&&x.endScope._multi?(d(), + u(x.endScope,e)):r.skip?A+=n:(r.returnEnd||r.excludeEnd||(A+=n), + d(),r.excludeEnd&&(A=n));do{ + x.scope&&S.closeNode(),x.skip||x.subLanguage||(C+=x.relevance),x=x.parent + }while(x!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:n.length} + let y={};function N(a,r){const o=r&&r[0];if(A+=a,null==o)return d(),0 + ;if("begin"===y.type&&"end"===r.type&&y.index===r.index&&""===o){ + if(A+=t.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`) + ;throw n.languageName=e,n.badRule=y.rule,n}return 1} + if(y=r,"begin"===r.type)return(e=>{ + const t=e[0],a=e.rule,i=new n(a),r=[a.__beforeBegin,a["on:begin"]] + ;for(const n of r)if(n&&(n(e,i),i.isMatchIgnored))return _(t) + ;return a.skip?A+=t:(a.excludeBegin&&(A+=t), + d(),a.returnBegin||a.excludeBegin||(A=t)),b(a,e),a.returnBegin?0:t.length})(r) ;if("illegal"===r.type&&!i){ - const e=Error('Illegal lexeme "'+o+'" for mode "'+(k.scope||"")+'"') - ;throw e.mode=k,e}if("end"===r.type){const e=_(r);if(e!==ee)return e} + const e=Error('Illegal lexeme "'+o+'" for mode "'+(x.scope||"")+'"') + ;throw e.mode=x,e}if("end"===r.type){const e=h(r);if(e!==ee)return e} if("illegal"===r.type&&""===o)return 1 - ;if(T>1e5&&T>3*r.index)throw Error("potential infinite loop, way more iterations than matches") - ;return S+=o,o.length}const w=v(e) + ;if(R>1e5&&R>3*r.index)throw Error("potential infinite loop, way more iterations than matches") + ;return A+=o,o.length}const w=v(e) ;if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"') - ;const N=Q(w);let O="",k=r||N;const x={},M=new d.__emitter(d);(()=>{const e=[] - ;for(let n=k;n!==w;n=n.parent)n.scope&&e.unshift(n.scope) - ;e.forEach((e=>M.openNode(e)))})();let S="",A=0,C=0,T=0,R=!1;try{ - for(k.matcher.considerAll();;){ - T++,R?R=!1:k.matcher.considerAll(),k.matcher.lastIndex=C - ;const e=k.matcher.exec(n);if(!e)break;const t=y(n.substring(C,e.index),e) - ;C=e.index+t} - return y(n.substring(C)),M.closeAllNodes(),M.finalize(),O=M.toHTML(),{ - language:e,value:O,relevance:A,illegal:!1,_emitter:M,_top:k}}catch(t){ - if(t.message&&t.message.includes("Illegal"))return{language:e,value:J(n), - illegal:!0,relevance:0,_illegalBy:{message:t.message,index:C, - context:n.slice(C-100,C+100),mode:t.mode,resultSoFar:O},_emitter:M};if(s)return{ - language:e,value:J(n),illegal:!1,relevance:0,errorRaised:t,_emitter:M,_top:k} - ;throw t}}function E(e,n){n=n||d.languages||Object.keys(a);const t=(e=>{ - const n={value:J(e),illegal:!1,relevance:0,_top:l,_emitter:new d.__emitter(d)} + ;const O=Q(w);let k="",x=r||O;const M={},S=new p.__emitter(p);(()=>{const e=[] + ;for(let n=x;n!==w;n=n.parent)n.scope&&e.unshift(n.scope) + ;e.forEach((e=>S.openNode(e)))})();let A="",C=0,T=0,R=0,D=!1;try{ + if(w.__emitTokens)w.__emitTokens(t,S);else{for(x.matcher.considerAll();;){ + R++,D?D=!1:x.matcher.considerAll(),x.matcher.lastIndex=T + ;const e=x.matcher.exec(t);if(!e)break;const n=N(t.substring(T,e.index),e) + ;T=e.index+n}N(t.substring(T))}return S.finalize(),k=S.toHTML(),{language:e, + value:k,relevance:C,illegal:!1,_emitter:S,_top:x}}catch(n){ + if(n.message&&n.message.includes("Illegal"))return{language:e,value:J(t), + illegal:!0,relevance:0,_illegalBy:{message:n.message,index:T, + context:t.slice(T-100,T+100),mode:n.mode,resultSoFar:k},_emitter:S};if(s)return{ + language:e,value:J(t),illegal:!1,relevance:0,errorRaised:n,_emitter:S,_top:x} + ;throw n}}function E(e,n){n=n||p.languages||Object.keys(a);const t=(e=>{ + const n={value:J(e),illegal:!1,relevance:0,_top:c,_emitter:new p.__emitter(p)} ;return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1))) ;i.unshift(t);const r=i.sort(((e,n)=>{ if(e.relevance!==n.relevance)return n.relevance-e.relevance ;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1 - ;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,c=s - ;return c.secondBest=o,c}function y(e){let n=null;const t=(e=>{ + ;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s + ;return l.secondBest=o,l}function y(e){let n=null;const t=(e=>{ let n=e.className+" ";n+=e.parentNode?e.parentNode.className:"" - ;const t=d.languageDetectRe.exec(n);if(t){const n=v(t[1]) + ;const t=p.languageDetectRe.exec(n);if(t){const n=v(t[1]) ;return n||(H(o.replace("{}",t[1])), H("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"} return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return ;if(x("before:highlightElement",{el:e,language:t - }),e.children.length>0&&(d.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), + }),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e) + ;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), console.warn("The element with unescaped HTML:"), - console.warn(e)),d.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML) + console.warn(e)),p.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML) ;n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a) - ;e.innerHTML=r.value,((e,n,t)=>{const a=n&&i[n]||t + ;e.innerHTML=r.value,e.dataset.highlighted="yes",((e,n,t)=>{const a=n&&i[n]||t ;e.classList.add("hljs"),e.classList.add("language-"+a) })(e,t,r.language),e.result={language:r.language,re:r.relevance, relevance:r.relevance},r.secondBest&&(e.secondBest={ language:r.secondBest.language,relevance:r.secondBest.relevance - }),x("after:highlightElement",{el:e,result:r,text:a})}let w=!1;function N(){ - "loading"!==document.readyState?document.querySelectorAll(d.cssSelector).forEach(y):w=!0 + }),x("after:highlightElement",{el:e,result:r,text:a})}let N=!1;function w(){ + "loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(y):N=!0 }function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]} function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ i[e.toLowerCase()]=n}))}function k(e){const n=v(e) ;return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{ e[t]&&e[t](n)}))} "undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ - w&&N()}),!1),Object.assign(n,{highlight:h,highlightAuto:E,highlightAll:N, + N&&w()}),!1),Object.assign(t,{highlight:h,highlightAuto:E,highlightAll:w, highlightElement:y, highlightBlock:e=>(q("10.7.0","highlightBlock will be removed entirely in v12.0"), - q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{d=Y(d,e)}, + q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{p=Y(p,e)}, initHighlighting:()=>{ - N(),q("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, + w(),q("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, initHighlightingOnLoad:()=>{ - N(),q("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") - },registerLanguage:(e,t)=>{let i=null;try{i=t(n)}catch(n){ + w(),q("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") + },registerLanguage:(e,n)=>{let i=null;try{i=n(t)}catch(n){ if(K("Language definition for '{}' could not be registered.".replace("{}",e)), - !s)throw n;K(n),i=l} - i.name||(i.name=e),a[e]=i,i.rawDefinition=t.bind(null,n),i.aliases&&O(i.aliases,{ + !s)throw n;K(n),i=c} + i.name||(i.name=e),a[e]=i,i.rawDefinition=n.bind(null,t),i.aliases&&O(i.aliases,{ languageName:e})},unregisterLanguage:e=>{delete a[e] ;for(const n of Object.keys(i))i[n]===e&&delete i[n]}, listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O, @@ -297,31 +300,32 @@ e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{ e["before:highlightBlock"](Object.assign({block:n.el},n)) }),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{ - e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)} - }),n.debugMode=()=>{s=!1},n.safeMode=()=>{s=!0 - },n.versionString="11.7.0",n.regex={concat:m,lookahead:g,either:p,optional:b, - anyNumberOfTimes:u};for(const n in T)"object"==typeof T[n]&&e.exports(T[n]) - ;return Object.assign(n,T),n})({});const te=e=>({IMPORTANT:{scope:"meta", - begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{ + e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)}, + removePlugin:e=>{const n=r.indexOf(e);-1!==n&&r.splice(n,1)}}),t.debugMode=()=>{ + s=!1},t.safeMode=()=>{s=!0},t.versionString="11.9.0",t.regex={concat:b, + lookahead:d,either:m,optional:u,anyNumberOfTimes:g} + ;for(const n in C)"object"==typeof C[n]&&e(C[n]);return Object.assign(t,C),t + },te=ne({});te.newInstance=()=>ne({});var ae=te;const ie=e=>({IMPORTANT:{ + scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{ scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/}, FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/}, ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ scope:"number", begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", - relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z][A-Za-z0-9_-]*/} - }),ae=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],ie=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],re=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],se=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],oe=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),le=re.concat(se) - ;var ce="\\.([0-9](_*[0-9])*)",de="[0-9a-fA-F](_*[0-9a-fA-F])*",ge={ + relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/} + }),re=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],se=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],oe=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],le=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ce=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),de=oe.concat(le) + ;var ge="[0-9](_*[0-9])*",ue=`\\.(${ge})`,be="[0-9a-fA-F](_*[0-9a-fA-F])*",me={ className:"number",variants:[{ - begin:`(\\b([0-9](_*[0-9])*)((${ce})|\\.)?|(${ce}))[eE][+-]?([0-9](_*[0-9])*)[fFdD]?\\b` - },{begin:`\\b([0-9](_*[0-9])*)((${ce})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{ - begin:`(${ce})[fFdD]?\\b`},{begin:"\\b([0-9](_*[0-9])*)[fFdD]\\b"},{ - begin:`\\b0[xX]((${de})\\.?|(${de})?\\.(${de}))[pP][+-]?([0-9](_*[0-9])*)[fFdD]?\\b` - },{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${de})[lL]?\\b`},{ + begin:`(\\b(${ge})((${ue})|\\.)?|(${ue}))[eE][+-]?(${ge})[fFdD]?\\b`},{ + begin:`\\b(${ge})((${ue})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{ + begin:`(${ue})[fFdD]?\\b`},{begin:`\\b(${ge})[fFdD]\\b`},{ + begin:`\\b0[xX]((${be})\\.?|(${be})?\\.(${be}))[pP][+-]?(${ge})[fFdD]?\\b`},{ + begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${be})[lL]?\\b`},{ begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}], - relevance:0};function ue(e,n,t){return-1===t?"":e.replace(n,(a=>ue(e,n,t-1)))} - const be="[A-Za-z$_][0-9A-Za-z$_]*",me=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],pe=["true","false","null","undefined","NaN","Infinity"],_e=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],he=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],fe=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],Ee=["arguments","this","super","console","window","document","localStorage","module","global"],ye=[].concat(fe,_e,he) - ;function we(e){const n=e.regex,t=be,a={begin:/<[A-Za-z0-9\\._:-]+/, + relevance:0};function pe(e,n,t){return-1===t?"":e.replace(n,(a=>pe(e,n,t-1)))} + const _e="[A-Za-z$_][0-9A-Za-z$_]*",he=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],fe=["true","false","null","undefined","NaN","Infinity"],Ee=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ye=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Ne=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],we=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],ve=[].concat(Ne,Ee,ye) + ;function Oe(e){const n=e.regex,t=_e,a={begin:/<[A-Za-z0-9\\._:-]+/, end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{ const t=e[0].length+e.index,a=e.input[t] ;if("<"===a||","===a)return void n.ignoreMatch();let i @@ -329,74 +333,76 @@ ;return-1!==e.input.indexOf(t,n)})(e,{after:t})||n.ignoreMatch()) ;const r=e.input.substring(t) ;((i=r.match(/^\s*=/))||(i=r.match(/^\s+extends\s+/))&&0===i.index)&&n.ignoreMatch() - }},i={$pattern:be,keyword:me,literal:pe,built_in:ye,"variable.language":Ee - },r="\\.([0-9](_?[0-9])*)",s="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",o={ + }},i={$pattern:_e,keyword:he,literal:fe,built_in:ve,"variable.language":we + },r="[0-9](_?[0-9])*",s=`\\.(${r})`,o="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",l={ className:"number",variants:[{ - begin:`(\\b(${s})((${r})|\\.)?|(${r}))[eE][+-]?([0-9](_?[0-9])*)\\b`},{ - begin:`\\b(${s})\\b((${r})\\b|\\.)?|(${r})\\b`},{ + begin:`(\\b(${o})((${s})|\\.)?|(${s}))[eE][+-]?(${r})\\b`},{ + begin:`\\b(${o})\\b((${s})\\b|\\.)?|(${s})\\b`},{ begin:"\\b(0|[1-9](_?[0-9])*)n\\b"},{ begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b"},{ begin:"\\b0[bB][0-1](_?[0-1])*n?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*n?\\b"},{ - begin:"\\b0[0-7]+n?\\b"}],relevance:0},l={className:"subst",begin:"\\$\\{", - end:"\\}",keywords:i,contains:[]},c={begin:"html`",end:"",starts:{end:"`", - returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,l],subLanguage:"xml"}},d={ + begin:"\\b0[0-7]+n?\\b"}],relevance:0},c={className:"subst",begin:"\\$\\{", + end:"\\}",keywords:i,contains:[]},d={begin:"html`",end:"",starts:{end:"`", + returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"xml"}},g={ begin:"css`",end:"",starts:{end:"`",returnEnd:!1, - contains:[e.BACKSLASH_ESCAPE,l],subLanguage:"css"}},g={className:"string", - begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE,l]},u={className:"comment", + contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"css"}},u={begin:"gql`",end:"", + starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c], + subLanguage:"graphql"}},b={className:"string",begin:"`",end:"`", + contains:[e.BACKSLASH_ESCAPE,c]},m={className:"comment", variants:[e.COMMENT(/\/\*\*(?!\/)/,"\\*/",{relevance:0,contains:[{ begin:"(?=@[A-Za-z]+)",relevance:0,contains:[{className:"doctag", begin:"@[A-Za-z]+"},{className:"type",begin:"\\{",end:"\\}",excludeEnd:!0, excludeBegin:!0,relevance:0},{className:"variable",begin:t+"(?=\\s*(-)|$)", endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}] }),e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE] - },b=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,c,d,g,{match:/\$\d+/},o] - ;l.contains=b.concat({begin:/\{/,end:/\}/,keywords:i,contains:["self"].concat(b) - });const m=[].concat(u,l.contains),p=m.concat([{begin:/\(/,end:/\)/,keywords:i, - contains:["self"].concat(m)}]),_={className:"params",begin:/\(/,end:/\)/, - excludeBegin:!0,excludeEnd:!0,keywords:i,contains:p},h={variants:[{ + },p=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,{match:/\$\d+/},l] + ;c.contains=p.concat({begin:/\{/,end:/\}/,keywords:i,contains:["self"].concat(p) + });const _=[].concat(m,c.contains),h=_.concat([{begin:/\(/,end:/\)/,keywords:i, + contains:["self"].concat(_)}]),f={className:"params",begin:/\(/,end:/\)/, + excludeBegin:!0,excludeEnd:!0,keywords:i,contains:h},E={variants:[{ match:[/class/,/\s+/,t,/\s+/,/extends/,/\s+/,n.concat(t,"(",n.concat(/\./,t),")*")], scope:{1:"keyword",3:"title.class",5:"keyword",7:"title.class.inherited"}},{ - match:[/class/,/\s+/,t],scope:{1:"keyword",3:"title.class"}}]},f={relevance:0, + match:[/class/,/\s+/,t],scope:{1:"keyword",3:"title.class"}}]},y={relevance:0, match:n.either(/\bJSON/,/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/), - className:"title.class",keywords:{_:[..._e,...he]}},E={variants:[{ + className:"title.class",keywords:{_:[...Ee,...ye]}},N={variants:[{ match:[/function/,/\s+/,t,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}], - className:{1:"keyword",3:"title.function"},label:"func.def",contains:[_], - illegal:/%/},y={ - match:n.concat(/\b/,(w=[...fe,"super","import"],n.concat("(?!",w.join("|"),")")),t,n.lookahead(/\(/)), - className:"title.function",relevance:0};var w;const N={ + className:{1:"keyword",3:"title.function"},label:"func.def",contains:[f], + illegal:/%/},w={ + match:n.concat(/\b/,(v=[...Ne,"super","import"],n.concat("(?!",v.join("|"),")")),t,n.lookahead(/\(/)), + className:"title.function",relevance:0};var v;const O={ begin:n.concat(/\./,n.lookahead(n.concat(t,/(?![0-9A-Za-z$_(])/))),end:t, - excludeBegin:!0,keywords:"prototype",className:"property",relevance:0},v={ + excludeBegin:!0,keywords:"prototype",className:"property",relevance:0},k={ match:[/get|set/,/\s+/,t,/(?=\()/],className:{1:"keyword",3:"title.function"}, - contains:[{begin:/\(\)/},_] - },O="(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+e.UNDERSCORE_IDENT_RE+")\\s*=>",k={ - match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(O)], - keywords:"async",className:{1:"keyword",3:"title.function"},contains:[_]} - ;return{name:"Javascript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{ - PARAMS_CONTAINS:p,CLASS_REFERENCE:f},illegal:/#(?![$_A-z])/, + contains:[{begin:/\(\)/},f] + },x="(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+e.UNDERSCORE_IDENT_RE+")\\s*=>",M={ + match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(x)], + keywords:"async",className:{1:"keyword",3:"title.function"},contains:[f]} + ;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{ + PARAMS_CONTAINS:h,CLASS_REFERENCE:y},illegal:/#(?![$_A-z])/, contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{ label:"use_strict",className:"meta",relevance:10, begin:/^\s*['"]use (strict|asm)['"]/ - },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,c,d,g,u,{match:/\$\d+/},o,f,{ - className:"attr",begin:t+n.lookahead(":"),relevance:0},k,{ + },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,m,{match:/\$\d+/},l,y,{ + className:"attr",begin:t+n.lookahead(":"),relevance:0},M,{ begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*", - keywords:"return throw case",relevance:0,contains:[u,e.REGEXP_MODE,{ - className:"function",begin:O,returnBegin:!0,end:"\\s*=>",contains:[{ + keywords:"return throw case",relevance:0,contains:[m,e.REGEXP_MODE,{ + className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{ className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{ className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0, - excludeEnd:!0,keywords:i,contains:p}]}]},{begin:/,/,relevance:0},{match:/\s+/, + excludeEnd:!0,keywords:i,contains:h}]}]},{begin:/,/,relevance:0},{match:/\s+/, relevance:0},{variants:[{begin:"<>",end:""},{ match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:a.begin, "on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{ - begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},E,{ + begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},N,{ beginKeywords:"while if switch catch for"},{ begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{", - returnBegin:!0,label:"func.def",contains:[_,e.inherit(e.TITLE_MODE,{begin:t, - className:"title.function"})]},{match:/\.\.\./,relevance:0},N,{match:"\\$"+t, + returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:t, + className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+t, relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"}, - contains:[_]},y,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, - className:"variable.constant"},h,v,{match:/\$[(.]/}]}} - const Ne=e=>m(/\b/,e,/\w$/.test(e)?/\b/:/\B/),ve=["Protocol","Type"].map(Ne),Oe=["init","self"].map(Ne),ke=["Any","Self"],xe=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","break","case","catch","class","continue","convenience","default","defer","deinit","didSet","distributed","do","dynamic","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Me=["false","nil","true"],Se=["assignment","associativity","higherThan","left","lowerThan","none","right"],Ae=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warn_unqualified_access","#warning"],Ce=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Te=p(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Re=p(Te,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),De=m(Te,Re,"*"),Ie=p(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),Le=p(Ie,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Be=m(Ie,Le,"*"),$e=m(/[A-Z]/,Le,"*"),ze=["autoclosure",m(/convention\(/,p("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",m(/objc\(/,Be,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","testable","UIApplicationMain","unknown","usableFromInline"],Fe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"] - ;var Ue=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={ + contains:[f]},w,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, + className:"variable.constant"},E,k,{match:/\$[(.]/}]}} + const ke=e=>b(/\b/,e,/\w$/.test(e)?/\b/:/\B/),xe=["Protocol","Type"].map(ke),Me=["init","self"].map(ke),Se=["Any","Self"],Ae=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Ce=["false","nil","true"],Te=["assignment","associativity","higherThan","left","lowerThan","none","right"],Re=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],De=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Ie=m(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Le=m(Ie,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),Be=b(Ie,Le,"*"),$e=m(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),ze=m($e,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Fe=b($e,ze,"*"),Ue=b(/[A-Z]/,ze,"*"),je=["attached","autoclosure",b(/convention\(/,m("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",b(/objc\(/,Fe,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","warn_unqualified_access"],Pe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"] + ;var Ke=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={ begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]} ;Object.assign(t,{className:"variable",variants:[{ begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={ @@ -409,92 +415,91 @@ }),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, - keyword:["if","then","else","elif","fi","for","while","in","do","done","case","esac","function"], + keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"], literal:["true","false"], built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] },contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{ - className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},t]}}, + match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}}, grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}] - }),a="[a-zA-Z_]\\w*::",i="(decltype\\(auto\\)|"+n.optional(a)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",r={ + }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{ - match:/\batomic_[a-z]{3,6}\b/}]},s={className:"string",variants:[{ + match:/\batomic_[a-z]{3,6}\b/}]},o={className:"string",variants:[{ begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ - begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},o={ + begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ className:"number",variants:[{begin:"\\b(0b[01']+)"},{ begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" },{ begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" - }],relevance:0},l={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ + }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" - },contains:[{begin:/\\\n/,relevance:0},e.inherit(s,{className:"string"}),{ - className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},c={ - className:"title",begin:n.optional(a)+e.IDENT_RE,relevance:0 - },d=n.optional(a)+e.IDENT_RE+"\\s*\\(",g={ + },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ + className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ + className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 + },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"], type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"], literal:"true false NULL", built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr" - },u=[l,r,t,e.C_BLOCK_COMMENT_MODE,o,s],b={variants:[{begin:/=/,end:/;/},{ + },b=[c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],m={variants:[{begin:/=/,end:/;/},{ begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], - keywords:g,contains:u.concat([{begin:/\(/,end:/\)/,keywords:g, - contains:u.concat(["self"]),relevance:0}]),relevance:0},m={ - begin:"("+i+"[\\*&\\s]+)+"+d,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, - keywords:g,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:"decltype\\(auto\\)", - keywords:g,relevance:0},{begin:d,returnBegin:!0,contains:[e.inherit(c,{ - className:"title.function"})],relevance:0},{relevance:0,match:/,/},{ - className:"params",begin:/\(/,end:/\)/,keywords:g,relevance:0, - contains:[t,e.C_BLOCK_COMMENT_MODE,s,o,r,{begin:/\(/,end:/\)/,keywords:g, - relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,s,o,r]}] - },r,t,e.C_BLOCK_COMMENT_MODE,l]};return{name:"C",aliases:["h"],keywords:g, - disableAutodetect:!0,illegal:".]/,contains:[{begin:a,keywords:u,relevance:0},{ + begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})], + relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/, + keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/, + end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s] + }]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u, + disableAutodetect:!0,illegal:"=]/,contains:[{ - beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:l, - strings:s,keywords:g}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{ + beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c, + strings:o,keywords:u}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{ contains:[{begin:/\\\n/}] - }),a="[a-zA-Z_]\\w*::",i="(?!struct)(decltype\\(auto\\)|"+n.optional(a)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",r={ - className:"type",begin:"\\b[a-z\\d_]*_t\\b"},s={className:"string",variants:[{ + }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="(?!struct)("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ + className:"type",begin:"\\b[a-z\\d_]*_t\\b"},o={className:"string",variants:[{ begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ - begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},o={ + begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ className:"number",variants:[{begin:"\\b(0b[01']+)"},{ begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" },{ begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" - }],relevance:0},l={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ + }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" - },contains:[{begin:/\\\n/,relevance:0},e.inherit(s,{className:"string"}),{ - className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},c={ - className:"title",begin:n.optional(a)+e.IDENT_RE,relevance:0 - },d=n.optional(a)+e.IDENT_RE+"\\s*\\(",g={ + },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ + className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ + className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 + },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"], keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"], literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"], _type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"] - },u={className:"function.dispatch",relevance:0,keywords:{ + },b={className:"function.dispatch",relevance:0,keywords:{ _hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"] }, begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/)) - },b=[u,l,r,t,e.C_BLOCK_COMMENT_MODE,o,s],m={variants:[{begin:/=/,end:/;/},{ + },m=[b,c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],p={variants:[{begin:/=/,end:/;/},{ begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], - keywords:g,contains:b.concat([{begin:/\(/,end:/\)/,keywords:g, - contains:b.concat(["self"]),relevance:0}]),relevance:0},p={className:"function", - begin:"("+i+"[\\*&\\s]+)+"+d,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, - keywords:g,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:"decltype\\(auto\\)", - keywords:g,relevance:0},{begin:d,returnBegin:!0,contains:[c],relevance:0},{ - begin:/::/,relevance:0},{begin:/:/,endsWithParent:!0,contains:[s,o]},{ - relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,keywords:g, - relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,s,o,r,{begin:/\(/,end:/\)/, - keywords:g,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,s,o,r]}] - },r,t,e.C_BLOCK_COMMENT_MODE,l]};return{name:"C++", - aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:g,illegal:".]/,contains:[{begin:a,keywords:u,relevance:0},{ + begin:g,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{ + begin:/:/,endsWithParent:!0,contains:[o,l]},{relevance:0,match:/,/},{ + className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0, + contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u, + relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}] + },s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C++", + aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:u,illegal:"",keywords:g,contains:["self",r]},{begin:e.IDENT_RE+"::",keywords:g},{ + end:">",keywords:u,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:u},{ match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/], className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={ keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]), @@ -541,15 +546,15 @@ begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0, contains:[g,a,e.C_BLOCK_COMMENT_MODE] },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{ - const n=e.regex,t=te(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{ + const n=e.regex,t=ie(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{ name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{ keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"}, contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/ },t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0 },{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0 },t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{ - begin:":("+re.join("|")+")"},{begin:":(:)?("+se.join("|")+")"}] - },t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+oe.join("|")+")\\b"},{ + begin:":("+oe.join("|")+")"},{begin:":(:)?("+le.join("|")+")"}] + },t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{ begin:/:/,end:/[;}{]/, contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{ begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri" @@ -557,9 +562,9 @@ excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]", relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/ },{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{ - $pattern:/[a-z-]+/,keyword:"and or not only",attribute:ie.join(" ")},contains:[{ + $pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{ begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{ - className:"selector-tag",begin:"\\b("+ae.join("|")+")\\b"}]}},grmr_diff:e=>{ + className:"selector-tag",begin:"\\b("+re.join("|")+")\\b"}]}},grmr_diff:e=>{ const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{ className:"meta",relevance:10, match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/) @@ -602,7 +607,7 @@ contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{ begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)), className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{ - const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+ue("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={ + const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+pe("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={ keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"], literal:["false","true","null"], type:["char","boolean","long","float","int","byte","short","double"], @@ -625,8 +630,8 @@ begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{ 2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/, end:/\)/,keywords:i,relevance:0, - contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,ge,e.C_BLOCK_COMMENT_MODE] - },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},ge,r]}},grmr_javascript:we, + contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,me,e.C_BLOCK_COMMENT_MODE] + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},me,r]}},grmr_javascript:Oe, grmr_json:e=>{const n=["true","false","null"],t={scope:"literal", beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{ className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{ @@ -645,7 +650,7 @@ begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?" },o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/, end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}] - },l=ge,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={ + },l=me,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={ variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/, contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g], {name:"Kotlin",aliases:["kt","kts"],keywords:n, @@ -668,41 +673,41 @@ excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/, excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env", end:"$",illegal:"\n"},l]}},grmr_less:e=>{ - const n=te(e),t=le,a="([\\w-]+|@\\{[\\w-]+\\})",i=[],r=[],s=e=>({ - className:"string",begin:"~?"+e+".*?"+e}),o=(e,n,t)=>({className:e,begin:n, - relevance:t}),l={$pattern:/[a-z-]+/,keyword:"and or not only", - attribute:ie.join(" ")},c={begin:"\\(",end:"\\)",contains:r,keywords:l, + const n=ie(e),t=de,a="[\\w-]+",i="("+a+"|@\\{"+a+"\\})",r=[],s=[],o=e=>({ + className:"string",begin:"~?"+e+".*?"+e}),l=(e,n,t)=>({className:e,begin:n, + relevance:t}),c={$pattern:/[a-z-]+/,keyword:"and or not only", + attribute:se.join(" ")},d={begin:"\\(",end:"\\)",contains:s,keywords:c, relevance:0} - ;r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s("'"),s('"'),n.CSS_NUMBER_MODE,{ + ;s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o("'"),o('"'),n.CSS_NUMBER_MODE,{ begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]", excludeEnd:!0} - },n.HEXCOLOR,c,o("variable","@@?[\\w-]+",10),o("variable","@\\{[\\w-]+\\}"),o("built_in","~?`[^`]*?`"),{ - className:"attribute",begin:"[\\w-]+\\s*:",end:":",returnBegin:!0,excludeEnd:!0 - },n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const d=r.concat({ - begin:/\{/,end:/\}/,contains:i}),g={beginKeywords:"when",endsWithParent:!0, - contains:[{beginKeywords:"and not"}].concat(r)},u={begin:a+"\\s*:", + },n.HEXCOLOR,d,l("variable","@@?"+a,10),l("variable","@\\{"+a+"\\}"),l("built_in","~?`[^`]*?`"),{ + className:"attribute",begin:a+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0 + },n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const g=s.concat({ + begin:/\{/,end:/\}/,contains:r}),u={beginKeywords:"when",endsWithParent:!0, + contains:[{beginKeywords:"and not"}].concat(s)},b={begin:i+"\\s*:", returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/ - },n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+oe.join("|")+")\\b", - end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:r}}] - },b={className:"keyword", + },n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b", + end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}] + },m={className:"keyword", begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b", - starts:{end:"[;{}]",keywords:l,returnEnd:!0,contains:r,relevance:0}},m={ - className:"variable",variants:[{begin:"@[\\w-]+\\s*:",relevance:15},{ - begin:"@[\\w-]+"}],starts:{end:"[;}]",returnEnd:!0,contains:d}},p={variants:[{ - begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:a,end:/\{/}],returnBegin:!0, + starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:s,relevance:0}},p={ + className:"variable",variants:[{begin:"@"+a+"\\s*:",relevance:15},{begin:"@"+a + }],starts:{end:"[;}]",returnEnd:!0,contains:g}},_={variants:[{ + begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:i,end:/\{/}],returnBegin:!0, returnEnd:!0,illegal:"[<='$\"]",relevance:0, - contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,g,o("keyword","all\\b"),o("variable","@\\{[\\w-]+\\}"),{ - begin:"\\b("+ae.join("|")+")\\b",className:"selector-tag" - },n.CSS_NUMBER_MODE,o("selector-tag",a,0),o("selector-id","#"+a),o("selector-class","\\."+a,0),o("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{ - className:"selector-pseudo",begin:":("+re.join("|")+")"},{ - className:"selector-pseudo",begin:":(:)?("+se.join("|")+")"},{begin:/\(/, - end:/\)/,relevance:0,contains:d},{begin:"!important"},n.FUNCTION_DISPATCH]},_={ - begin:`[\\w-]+:(:)?(${t.join("|")})`,returnBegin:!0,contains:[p]} - ;return i.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,b,m,_,u,p,g,n.FUNCTION_DISPATCH), - {name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:i}}, + contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,l("keyword","all\\b"),l("variable","@\\{"+a+"\\}"),{ + begin:"\\b("+re.join("|")+")\\b",className:"selector-tag" + },n.CSS_NUMBER_MODE,l("selector-tag",i,0),l("selector-id","#"+i),l("selector-class","\\."+i,0),l("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{ + className:"selector-pseudo",begin:":("+oe.join("|")+")"},{ + className:"selector-pseudo",begin:":(:)?("+le.join("|")+")"},{begin:/\(/, + end:/\)/,relevance:0,contains:g},{begin:"!important"},n.FUNCTION_DISPATCH]},h={ + begin:a+":(:)?"+`(${t.join("|")})`,returnBegin:!0,contains:[_]} + ;return r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,m,p,h,b,_,u,n.FUNCTION_DISPATCH), + {name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:r}}, grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={begin:n,end:t,contains:["self"] - },i=[e.COMMENT("--(?!\\[=*\\[)","$"),e.COMMENT("--\\[=*\\[",t,{contains:[a], - relevance:10})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE, + },i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,t,{contains:[a],relevance:10 + })];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE, literal:"true false nil", keyword:"and break do else elseif end for goto if in local not or repeat return then until while", built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove" @@ -722,35 +727,9 @@ name:"Makefile",aliases:["mk","mak","make"],keywords:{$pattern:/[\w-]+/, keyword:"define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath" },contains:[e.HASH_COMMENT_MODE,n,t,a,i,{className:"meta",begin:/^\.PHONY:/, - end:/$/,keywords:{$pattern:/[\.\w]+/,keyword:".PHONY"}},r]}},grmr_xml:e=>{ - const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={ - className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/, - contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] - },r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{ - className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={ - endsWithParent:!0,illegal:/`]+/}]}]}]};return{ - name:"HTML, XML", - aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], - case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{ - className:"meta",begin://,contains:[i,r,o,s]}]}] - },e.COMMENT(//,{relevance:10}),{begin://, - relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, - relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", - begin:/)/,end:/>/,keywords:{name:"style"},contains:[l],starts:{ - end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", - begin:/)/,end:/>/,keywords:{name:"script"},contains:[l],starts:{ - end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ - className:"tag",begin:/<>|<\/>/},{className:"tag", - begin:n.concat(//,/>/,/\s/)))), - end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{ - className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(t,/>/))),contains:[{ - className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]} - },grmr_markdown:e=>{const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml", - relevance:0},t={variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{ + end:/$/,keywords:{$pattern:/[\.\w]+/,keyword:".PHONY"}},r]}},grmr_markdown:e=>{ + const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={ + variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{ begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, relevance:2},{ begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/), @@ -836,11 +815,13 @@ scope:"variable",match:"\\$+"+a},s={scope:"subst",variants:[{begin:/\$\w+/},{ begin:/\{\$/,end:/\}/}]},o=e.inherit(e.APOS_STRING_MODE,{illegal:null }),l="[ \t\n]",c={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{ - illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s) - }),o,e.END_SAME_AS_BEGIN({begin:/<<<[ \t]*(\w+)\n/,end:/[ \t]*(\w+)\b/, - contains:e.QUOTE_STRING_MODE.contains.concat(s)})]},d={scope:"number", - variants:[{begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{ - begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{ + illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s)}),o,{ + begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/, + contains:e.QUOTE_STRING_MODE.contains.concat(s),"on:begin":(e,n)=>{ + n.data._beginMatch=e[1]||e[2]},"on:end":(e,n)=>{ + n.data._beginMatch!==e[1]&&n.ignoreMatch()}},e.END_SAME_AS_BEGIN({ + begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},d={scope:"number",variants:[{ + begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{ begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{ begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?" }],relevance:0 @@ -858,20 +839,20 @@ 3:"variable.language"}}]},E={scope:"attr", match:n.concat(a,n.lookahead(":"),n.lookahead(/(?!::)/))},y={relevance:0, begin:/\(/,end:/\)/,keywords:m,contains:[E,r,f,e.C_BLOCK_COMMENT_MODE,c,d,_] - },w={relevance:0, + },N={relevance:0, match:[/\b/,n.concat("(?!fn\\b|function\\b|",p(u).join("\\b|"),"|",p(b).join("\\b|"),"\\b)"),a,n.concat(l,"*"),n.lookahead(/(?=\()/)], - scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(w) - ;const N=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1, + scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(N) + ;const w=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1, keywords:m,contains:[{begin:n.concat(/#\[\s*/,i),beginScope:"meta",end:/]/, endScope:"meta",keywords:{literal:g,keyword:["new","array"]},contains:[{ begin:/\[/,end:/]/,keywords:{literal:g,keyword:["new","array"]}, - contains:["self",...N]},...N,{scope:"meta",match:i}] + contains:["self",...w]},...w,{scope:"meta",match:i}] },e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{ scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/, keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE, contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{ begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{ - begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,w,f,{ + begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,N,f,{ match:[/const/,/\s/,a],scope:{1:"keyword",3:"variable.constant"}},_,{ scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/, excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use" @@ -924,7 +905,7 @@ end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i, contains:["self",r,u,l,e.HASH_COMMENT_MODE]}]};return s.contains=[l,u,r],{ name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i, - illegal:/(<\/|->|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if", + illegal:/(<\/|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if", relevance:0},l,b,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,t],scope:{ 1:"keyword",3:"title.function"},contains:[m]},{variants:[{ match:[/\bclass/,/\s+/,t,/\s*/,/\(\s*/,t,/\s*\)/]},{match:[/\bclass/,/\s+/,t]}], @@ -1009,8 +990,8 @@ aliases:["rb","gemspec","podspec","thor","irb"],keywords:r,illegal:/\/\*/, contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(l).concat(m)}}, grmr_rust:e=>{const n=e.regex,t={className:"title.function.invoke",relevance:0, - begin:n.concat(/\b/,/(?!let\b)/,e.IDENT_RE,n.lookahead(/\s*\(/)) - },a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"] + begin:n.concat(/\b/,/(?!let|for|while|if|else|match\b)/,e.IDENT_RE,n.lookahead(/\s*\(/)) + },a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"] ;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r, keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"], literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:""},t]}}, - grmr_scss:e=>{const n=te(e),t=se,a=re,i="@[a-z-]+",r={className:"variable", + grmr_scss:e=>{const n=ie(e),t=le,a=oe,i="@[a-z-]+",r={className:"variable", begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS", case_insensitive:!0,illegal:"[=/|']", contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n.CSS_NUMBER_MODE,{ className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{ className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0 },n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag", - begin:"\\b("+ae.join("|")+")\\b",relevance:0},{className:"selector-pseudo", + begin:"\\b("+re.join("|")+")\\b",relevance:0},{className:"selector-pseudo", begin:":("+a.join("|")+")"},{className:"selector-pseudo", begin:":(:)?("+t.join("|")+")"},r,{begin:/\(/,end:/\)/, contains:[n.CSS_NUMBER_MODE]},n.CSS_VARIABLE,{className:"attribute", - begin:"\\b("+oe.join("|")+")\\b"},{ + begin:"\\b("+ce.join("|")+")\\b"},{ begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b" },{begin:/:/,end:/[;}{]/,relevance:0, contains:[n.BLOCK_COMMENT,r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT,n.FUNCTION_DISPATCH] },{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{ begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/, - keyword:"and or not only",attribute:ie.join(" ")},contains:[{begin:i, + keyword:"and or not only",attribute:se.join(" ")},contains:[{begin:i, className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute" },r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE] },n.FUNCTION_DISPATCH]}},grmr_shell:e=>({name:"Shell Session", @@ -1067,78 +1048,81 @@ },contains:[{begin:n.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/, keyword:l.concat(s),literal:a,type:i}},{className:"type", begin:n.either("double precision","large object","with timezone","without timezone") - },c,{className:"variable",begin:/@[a-z0-9]+/},{className:"string",variants:[{ - begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/,contains:[{ - begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{className:"operator", - begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,relevance:0}]}}, - grmr_swift:e=>{const n={match:/\s+/,relevance:0},t=e.COMMENT("/\\*","\\*/",{ - contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={match:[/\./,p(...ve,...Oe)], - className:{2:"keyword"}},r={match:m(/\./,p(...xe)),relevance:0 - },s=xe.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{ + },c,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string", + variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/, + contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{ + className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/, + relevance:0}]}},grmr_swift:e=>{const n={match:/\s+/,relevance:0 + },t=e.COMMENT("/\\*","\\*/",{contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={ + match:[/\./,m(...xe,...Me)],className:{2:"keyword"}},r={match:b(/\./,m(...Ae)), + relevance:0},s=Ae.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{ className:"keyword", - match:p(...xe.filter((e=>"string"!=typeof e)).concat(ke).map(Ne),...Oe)}]},l={ - $pattern:p(/\b\w+/,/#\w+/),keyword:s.concat(Ae),literal:Me},c=[i,r,o],d=[{ - match:m(/\./,p(...Ce)),relevance:0},{className:"built_in", - match:m(/\b/,p(...Ce),/(?=\()/)}],u={match:/->/,relevance:0},b=[u,{ - className:"operator",relevance:0,variants:[{match:De},{match:`\\.(\\.|${Re})+`}] - }],_="([0-9a-fA-F]_*)+",h={className:"number",relevance:0,variants:[{ - match:"\\b(([0-9]_*)+)(\\.(([0-9]_*)+))?([eE][+-]?(([0-9]_*)+))?\\b"},{ - match:`\\b0x(${_})(\\.(${_}))?([pP][+-]?(([0-9]_*)+))?\\b`},{ - match:/\b0o([0-7]_*)+\b/},{match:/\b0b([01]_*)+\b/}]},f=(e="")=>({ - className:"subst",variants:[{match:m(/\\/,e,/[0\\tnr"']/)},{ - match:m(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}]}),E=(e="")=>({className:"subst", - match:m(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/)}),y=(e="")=>({className:"subst", - label:"interpol",begin:m(/\\/,e,/\(/),end:/\)/}),w=(e="")=>({begin:m(e,/"""/), - end:m(/"""/,e),contains:[f(e),E(e),y(e)]}),N=(e="")=>({begin:m(e,/"/), - end:m(/"/,e),contains:[f(e),y(e)]}),v={className:"string", - variants:[w(),w("#"),w("##"),w("###"),N(),N("#"),N("##"),N("###")]},O={ - match:m(/`/,Be,/`/)},k=[O,{className:"variable",match:/\$\d+/},{ - className:"variable",match:`\\$${Le}+`}],x=[{match:/(@|#(un)?)available/, - className:"keyword",starts:{contains:[{begin:/\(/,end:/\)/,keywords:Fe, - contains:[...b,h,v]}]}},{className:"keyword",match:m(/@/,p(...ze))},{ - className:"meta",match:m(/@/,Be)}],M={match:g(/\b[A-Z]/),relevance:0,contains:[{ - className:"type", - match:m(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,Le,"+") - },{className:"type",match:$e,relevance:0},{match:/[?!]+/,relevance:0},{ - match:/\.\.\./,relevance:0},{match:m(/\s+&\s+/,g($e)),relevance:0}]},S={ - begin://,keywords:l,contains:[...a,...c,...x,u,M]};M.contains.push(S) - ;const A={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{ - match:m(Be,/\s*:/),keywords:"_|0",relevance:0 - },...a,...c,...d,...b,h,v,...k,...x,M]},C={begin://,contains:[...a,M] - },T={begin:/\(/,end:/\)/,keywords:l,contains:[{ - begin:p(g(m(Be,/\s*:/)),g(m(Be,/\s+/,Be,/\s*:/))),end:/:/,relevance:0, - contains:[{className:"keyword",match:/\b_\b/},{className:"params",match:Be}] - },...a,...c,...b,h,v,...x,M,A],endsParent:!0,illegal:/["']/},R={ - match:[/func/,/\s+/,p(O.match,Be,De)],className:{1:"keyword",3:"title.function" - },contains:[C,T,n],illegal:[/\[/,/%/]},D={ + match:m(...Ae.filter((e=>"string"!=typeof e)).concat(Se).map(ke),...Me)}]},l={ + $pattern:m(/\b\w+/,/#\w+/),keyword:s.concat(Re),literal:Ce},c=[i,r,o],g=[{ + match:b(/\./,m(...De)),relevance:0},{className:"built_in", + match:b(/\b/,m(...De),/(?=\()/)}],u={match:/->/,relevance:0},p=[u,{ + className:"operator",relevance:0,variants:[{match:Be},{match:`\\.(\\.|${Le})+`}] + }],_="([0-9]_*)+",h="([0-9a-fA-F]_*)+",f={className:"number",relevance:0, + variants:[{match:`\\b(${_})(\\.(${_}))?([eE][+-]?(${_}))?\\b`},{ + match:`\\b0x(${h})(\\.(${h}))?([pP][+-]?(${_}))?\\b`},{match:/\b0o([0-7]_*)+\b/ + },{match:/\b0b([01]_*)+\b/}]},E=(e="")=>({className:"subst",variants:[{ + match:b(/\\/,e,/[0\\tnr"']/)},{match:b(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}] + }),y=(e="")=>({className:"subst",match:b(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/) + }),N=(e="")=>({className:"subst",label:"interpol",begin:b(/\\/,e,/\(/),end:/\)/ + }),w=(e="")=>({begin:b(e,/"""/),end:b(/"""/,e),contains:[E(e),y(e),N(e)] + }),v=(e="")=>({begin:b(e,/"/),end:b(/"/,e),contains:[E(e),N(e)]}),O={ + className:"string", + variants:[w(),w("#"),w("##"),w("###"),v(),v("#"),v("##"),v("###")] + },k=[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0, + contains:[e.BACKSLASH_ESCAPE]}],x={begin:/\/[^\s](?=[^/\n]*\/)/,end:/\//, + contains:k},M=e=>{const n=b(e,/\//),t=b(/\//,e);return{begin:n,end:t, + contains:[...k,{scope:"comment",begin:`#(?!.*${t})`,end:/$/}]}},S={ + scope:"regexp",variants:[M("###"),M("##"),M("#"),x]},A={match:b(/`/,Fe,/`/) + },C=[A,{className:"variable",match:/\$\d+/},{className:"variable", + match:`\\$${ze}+`}],T=[{match:/(@|#(un)?)available/,scope:"keyword",starts:{ + contains:[{begin:/\(/,end:/\)/,keywords:Pe,contains:[...p,f,O]}]}},{ + scope:"keyword",match:b(/@/,m(...je))},{scope:"meta",match:b(/@/,Fe)}],R={ + match:d(/\b[A-Z]/),relevance:0,contains:[{className:"type", + match:b(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,ze,"+") + },{className:"type",match:Ue,relevance:0},{match:/[?!]+/,relevance:0},{ + match:/\.\.\./,relevance:0},{match:b(/\s+&\s+/,d(Ue)),relevance:0}]},D={ + begin://,keywords:l,contains:[...a,...c,...T,u,R]};R.contains.push(D) + ;const I={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{ + match:b(Fe,/\s*:/),keywords:"_|0",relevance:0 + },...a,S,...c,...g,...p,f,O,...C,...T,R]},L={begin://, + keywords:"repeat each",contains:[...a,R]},B={begin:/\(/,end:/\)/,keywords:l, + contains:[{begin:m(d(b(Fe,/\s*:/)),d(b(Fe,/\s+/,Fe,/\s*:/))),end:/:/, + relevance:0,contains:[{className:"keyword",match:/\b_\b/},{className:"params", + match:Fe}]},...a,...c,...p,f,O,...T,R,I],endsParent:!0,illegal:/["']/},$={ + match:[/(func|macro)/,/\s+/,m(A.match,Fe,Be)],className:{1:"keyword", + 3:"title.function"},contains:[L,B,n],illegal:[/\[/,/%/]},z={ match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"}, - contains:[C,T,n],illegal:/\[|%/},I={match:[/operator/,/\s+/,De],className:{ - 1:"keyword",3:"title"}},L={begin:[/precedencegroup/,/\s+/,$e],className:{ - 1:"keyword",3:"title"},contains:[M],keywords:[...Se,...Me],end:/}/} - ;for(const e of v.variants){const n=e.contains.find((e=>"interpol"===e.label)) - ;n.keywords=l;const t=[...c,...d,...b,h,v,...k];n.contains=[...t,{begin:/\(/, + contains:[L,B,n],illegal:/\[|%/},F={match:[/operator/,/\s+/,Be],className:{ + 1:"keyword",3:"title"}},U={begin:[/precedencegroup/,/\s+/,Ue],className:{ + 1:"keyword",3:"title"},contains:[R],keywords:[...Te,...Ce],end:/}/} + ;for(const e of O.variants){const n=e.contains.find((e=>"interpol"===e.label)) + ;n.keywords=l;const t=[...c,...g,...p,f,O,...C];n.contains=[...t,{begin:/\(/, end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:l, - contains:[...a,R,D,{beginKeywords:"struct protocol class extension enum actor", + contains:[...a,$,z,{beginKeywords:"struct protocol class extension enum actor", end:"\\{",excludeEnd:!0,keywords:l,contains:[e.inherit(e.TITLE_MODE,{ className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c] - },I,L,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0 - },...c,...d,...b,h,v,...k,...x,M,A]}},grmr_typescript:e=>{ - const n=we(e),t=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],a={ + },F,U,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0 + },S,...c,...g,...p,f,O,...C,...T,R,I]}},grmr_typescript:e=>{ + const n=Oe(e),t=_e,a=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],i={ beginKeywords:"namespace",end:/\{/,excludeEnd:!0, - contains:[n.exports.CLASS_REFERENCE]},i={beginKeywords:"interface",end:/\{/, - excludeEnd:!0,keywords:{keyword:"interface extends",built_in:t}, - contains:[n.exports.CLASS_REFERENCE]},r={$pattern:be, - keyword:me.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]), - literal:pe,built_in:ye.concat(t),"variable.language":Ee},s={className:"meta", - begin:"@[A-Za-z$_][0-9A-Za-z$_]*"},o=(e,n,t)=>{ - const a=e.contains.findIndex((e=>e.label===n)) + contains:[n.exports.CLASS_REFERENCE]},r={beginKeywords:"interface",end:/\{/, + excludeEnd:!0,keywords:{keyword:"interface extends",built_in:a}, + contains:[n.exports.CLASS_REFERENCE]},s={$pattern:_e, + keyword:he.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]), + literal:fe,built_in:ve.concat(a),"variable.language":we},o={className:"meta", + begin:"@"+t},l=(e,n,t)=>{const a=e.contains.findIndex((e=>e.label===n)) ;if(-1===a)throw Error("can not find mode to replace");e.contains.splice(a,1,t)} - ;return Object.assign(n.keywords,r), - n.exports.PARAMS_CONTAINS.push(s),n.contains=n.contains.concat([s,a,i]), - o(n,"shebang",e.SHEBANG()),o(n,"use_strict",{className:"meta",relevance:10, + ;return Object.assign(n.keywords,s), + n.exports.PARAMS_CONTAINS.push(o),n.contains=n.contains.concat([o,i,r]), + l(n,"shebang",e.SHEBANG()),l(n,"use_strict",{className:"meta",relevance:10, begin:/^\s*['"]use strict['"]/ }),n.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(n,{ - name:"TypeScript",aliases:["ts","tsx"]}),n},grmr_vbnet:e=>{ + name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),n},grmr_vbnet:e=>{ const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,r=/\d{1,2}(:\d{1,2}){1,2}/,s={ className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{ begin:n.concat(/# */,r,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{ @@ -1173,7 +1157,34 @@ match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/ },{className:"number",relevance:0, match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/ - }]}},grmr_yaml:e=>{ + }]}},grmr_xml:e=>{ + const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={ + className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/, + contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] + },r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{ + className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={ + endsWithParent:!0,illegal:/`]+/}]}]}]};return{ + name:"HTML, XML", + aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], + case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{ + className:"meta",begin://,contains:[i,r,o,s]}]}] + },e.COMMENT(//,{relevance:10}),{begin://, + relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, + relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", + begin:/)/,end:/>/,keywords:{name:"style"},contains:[l],starts:{ + end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", + begin:/)/,end:/>/,keywords:{name:"script"},contains:[l],starts:{ + end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ + className:"tag",begin:/<>|<\/>/},{className:"tag", + begin:n.concat(//,/>/,/\s/)))), + end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{ + className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(t,/>/))),contains:[{ + className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]} + },grmr_yaml:e=>{ const n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={ className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/ },{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable", @@ -1196,8 +1207,7 @@ begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b" },{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,o,a],c=[...l] ;return c.pop(),c.push(i),r.contains=c,{name:"YAML",case_insensitive:!0, - aliases:["yml"],contains:l}}});const je=ne;for(const e of Object.keys(Ue)){ - const n=e.replace("grmr_","").replace("_","-");je.registerLanguage(n,Ue[e])} - return je}() - ;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); - \ No newline at end of file + aliases:["yml"],contains:l}}});const He=ae;for(const e of Object.keys(Ke)){ + const n=e.replace("grmr_","").replace("_","-");He.registerLanguage(n,Ke[e])} + return He}() + ;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); \ No newline at end of file diff --git a/Desktop/html/js/jaspNotes.js b/Desktop/html/js/jaspNotes.js index 72ff77a21a..5ba081a339 100644 --- a/Desktop/html/js/jaspNotes.js +++ b/Desktop/html/js/jaspNotes.js @@ -22,7 +22,7 @@ function isURLInWhitelist(hostname) { if (insideJASP) { var Parchment = Quill.import('parchment'); - var LineBreakClass = new Parchment.Attributor.Class('linebreak', 'linebreak', { + var LineBreakClass = new Parchment.ClassAttributor('linebreak', 'linebreak', { scope: Parchment.Scope.BLOCK }); @@ -30,12 +30,36 @@ if (insideJASP) { // using https://github.com/Fandom-OSS/quill-blot-formatter to format image Quill.register('modules/blotFormatter', QuillBlotFormatter.default); + + // custom delet behaviors becaus of https://github.com/jasp-stats/jasp-issues/issues/2776 + class _CustomDeleteAction extends QuillBlotFormatter.DeleteAction { + constructor(formatter) { + super(formatter); + } + + onKeyUp = (e) => { + if (!this.formatter.currentSpec) + return; + + if (e.key === 'Backspace' || e.key === 'Delete') { + const blot = Quill.find(this.formatter.currentSpec.getTargetElement()); + if (blot) + blot.deleteAt(0); + this.formatter.hide(); + } + }; + } + class _CustomImageSpec extends QuillBlotFormatter.ImageSpec { constructor(formatter) { super(formatter); this.img = null; } + getActions() { + return [QuillBlotFormatter.AlignAction, QuillBlotFormatter.ResizeAction, _CustomDeleteAction]; + } + onClick = (event) => { const el = event.target; @@ -45,6 +69,11 @@ if (insideJASP) { this.img = el; this.formatter.show(this); + + const $thisOverlay = $(this.formatter.overlay); + // auto show/hide image editor toolbar with mouse action + $thisOverlay.on("mouseenter", () => { $thisOverlay.show() }).on("mouseleave", () => { $thisOverlay.hide() }); + $(this.img).on( "mouseenter", () => { $thisOverlay.show() }).on("mouseleave", () => { $thisOverlay.hide() }); }; } var CustomImageSpec = _CustomImageSpec @@ -491,14 +520,6 @@ JASPWidgets.NoteBox = JASPWidgets.View.extend({ self.oldBlot = self.formulaBlot // Get legacy formula range to remove while save }); - ////--- Image resizer ---//// - let $imgBlot = this.$el.find('.ql-editor p img'); - let $blotResizer = this.$el.find('.blot-formatter__overlay'); - let $resizeHandles = this.$el.find('[class^="blot-formatter"]'); - - $blotResizer.on("mouseenter", () => { $resizeHandles.show() }).on("mouseleave", () => { $resizeHandles.hide() }); - $imgBlot.on( "mouseenter", () => { $resizeHandles.show() }).on("mouseleave", () => { $resizeHandles.hide() }); - }); quillEditorElement.addEventListener('focusin', () => { diff --git a/Desktop/html/js/jaspwidgets.js b/Desktop/html/js/jaspwidgets.js index 348b1473c7..c87a99cf6a 100644 --- a/Desktop/html/js/jaspwidgets.js +++ b/Desktop/html/js/jaspwidgets.js @@ -641,8 +641,7 @@ JASPWidgets.RSyntaxView = JASPWidgets.View.extend({ .html("
" + rScript + "
"); setTimeout(() => { this.$el.find(".jasp-rsyntax")[0].querySelectorAll('pre code').forEach((el) => { - el.innerHTML = el.textContent; //Suppress warnings of html code tags - hljs.highlightElement(el); + el.innerHTML = hljs.highlight(el.textContent, { language: 'r' }).value; }); }, 200); }, diff --git a/Desktop/html/js/quill.js b/Desktop/html/js/quill.js index bee4110fc2..080847a236 100644 --- a/Desktop/html/js/quill.js +++ b/Desktop/html/js/quill.js @@ -1,11571 +1,9 @@ -/*! - * Quill Editor v1.3.7 - * https://quilljs.com/ +/*! + * Quill Editor v2.0.2 + * https://quilljs.com + * Copyright (c) 2017-2024, Slab * Copyright (c) 2014, Jason Chen * Copyright (c) 2013, salesforce.com + * For license information please see quill.js.LICENSE.txt */ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["Quill"] = factory(); - else - root["Quill"] = factory(); -})(typeof self !== 'undefined' ? self : this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 109); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(17); -var format_1 = __webpack_require__(18); -var leaf_1 = __webpack_require__(19); -var scroll_1 = __webpack_require__(45); -var inline_1 = __webpack_require__(46); -var block_1 = __webpack_require__(47); -var embed_1 = __webpack_require__(48); -var text_1 = __webpack_require__(49); -var attributor_1 = __webpack_require__(12); -var class_1 = __webpack_require__(32); -var style_1 = __webpack_require__(33); -var store_1 = __webpack_require__(31); -var Registry = __webpack_require__(1); -var Parchment = { - Scope: Registry.Scope, - create: Registry.create, - find: Registry.find, - query: Registry.query, - register: Registry.register, - Container: container_1.default, - Format: format_1.default, - Leaf: leaf_1.default, - Embed: embed_1.default, - Scroll: scroll_1.default, - Block: block_1.default, - Inline: inline_1.default, - Text: text_1.default, - Attributor: { - Attribute: attributor_1.default, - Class: class_1.default, - Style: style_1.default, - Store: store_1.default, - }, -}; -exports.default = Parchment; - - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var ParchmentError = /** @class */ (function (_super) { - __extends(ParchmentError, _super); - function ParchmentError(message) { - var _this = this; - message = '[Parchment] ' + message; - _this = _super.call(this, message) || this; - _this.message = message; - _this.name = _this.constructor.name; - return _this; - } - return ParchmentError; -}(Error)); -exports.ParchmentError = ParchmentError; -var attributes = {}; -var classes = {}; -var tags = {}; -var types = {}; -exports.DATA_KEY = '__blot'; -var Scope; -(function (Scope) { - Scope[Scope["TYPE"] = 3] = "TYPE"; - Scope[Scope["LEVEL"] = 12] = "LEVEL"; - Scope[Scope["ATTRIBUTE"] = 13] = "ATTRIBUTE"; - Scope[Scope["BLOT"] = 14] = "BLOT"; - Scope[Scope["INLINE"] = 7] = "INLINE"; - Scope[Scope["BLOCK"] = 11] = "BLOCK"; - Scope[Scope["BLOCK_BLOT"] = 10] = "BLOCK_BLOT"; - Scope[Scope["INLINE_BLOT"] = 6] = "INLINE_BLOT"; - Scope[Scope["BLOCK_ATTRIBUTE"] = 9] = "BLOCK_ATTRIBUTE"; - Scope[Scope["INLINE_ATTRIBUTE"] = 5] = "INLINE_ATTRIBUTE"; - Scope[Scope["ANY"] = 15] = "ANY"; -})(Scope = exports.Scope || (exports.Scope = {})); -function create(input, value) { - var match = query(input); - if (match == null) { - throw new ParchmentError("Unable to create " + input + " blot"); - } - var BlotClass = match; - var node = - // @ts-ignore - input instanceof Node || input['nodeType'] === Node.TEXT_NODE ? input : BlotClass.create(value); - return new BlotClass(node, value); -} -exports.create = create; -function find(node, bubble) { - if (bubble === void 0) { bubble = false; } - if (node == null) - return null; - // @ts-ignore - if (node[exports.DATA_KEY] != null) - return node[exports.DATA_KEY].blot; - if (bubble) - return find(node.parentNode, bubble); - return null; -} -exports.find = find; -function query(query, scope) { - if (scope === void 0) { scope = Scope.ANY; } - var match; - if (typeof query === 'string') { - match = types[query] || attributes[query]; - // @ts-ignore - } - else if (query instanceof Text || query['nodeType'] === Node.TEXT_NODE) { - match = types['text']; - } - else if (typeof query === 'number') { - if (query & Scope.LEVEL & Scope.BLOCK) { - match = types['block']; - } - else if (query & Scope.LEVEL & Scope.INLINE) { - match = types['inline']; - } - } - else if (query instanceof HTMLElement) { - var names = (query.getAttribute('class') || '').split(/\s+/); - for (var i in names) { - match = classes[names[i]]; - if (match) - break; - } - match = match || tags[query.tagName]; - } - if (match == null) - return null; - // @ts-ignore - if (scope & Scope.LEVEL & match.scope && scope & Scope.TYPE & match.scope) - return match; - return null; -} -exports.query = query; -function register() { - var Definitions = []; - for (var _i = 0; _i < arguments.length; _i++) { - Definitions[_i] = arguments[_i]; - } - if (Definitions.length > 1) { - return Definitions.map(function (d) { - return register(d); - }); - } - var Definition = Definitions[0]; - if (typeof Definition.blotName !== 'string' && typeof Definition.attrName !== 'string') { - throw new ParchmentError('Invalid definition'); - } - else if (Definition.blotName === 'abstract') { - throw new ParchmentError('Cannot register abstract class'); - } - types[Definition.blotName || Definition.attrName] = Definition; - if (typeof Definition.keyName === 'string') { - attributes[Definition.keyName] = Definition; - } - else { - if (Definition.className != null) { - classes[Definition.className] = Definition; - } - if (Definition.tagName != null) { - if (Array.isArray(Definition.tagName)) { - Definition.tagName = Definition.tagName.map(function (tagName) { - return tagName.toUpperCase(); - }); - } - else { - Definition.tagName = Definition.tagName.toUpperCase(); - } - var tagNames = Array.isArray(Definition.tagName) ? Definition.tagName : [Definition.tagName]; - tagNames.forEach(function (tag) { - if (tags[tag] == null || Definition.className == null) { - tags[tag] = Definition; - } - }); - } - } - return Definition; -} -exports.register = register; - - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -var diff = __webpack_require__(51); -var equal = __webpack_require__(11); -var extend = __webpack_require__(3); -var op = __webpack_require__(20); - - -var NULL_CHARACTER = String.fromCharCode(0); // Placeholder char for embed in diff() - - -var Delta = function (ops) { - // Assume we are given a well formed ops - if (Array.isArray(ops)) { - this.ops = ops; - } else if (ops != null && Array.isArray(ops.ops)) { - this.ops = ops.ops; - } else { - this.ops = []; - } -}; - - -Delta.prototype.insert = function (text, attributes) { - var newOp = {}; - if (text.length === 0) return this; - newOp.insert = text; - if (attributes != null && typeof attributes === 'object' && Object.keys(attributes).length > 0) { - newOp.attributes = attributes; - } - return this.push(newOp); -}; - -Delta.prototype['delete'] = function (length) { - if (length <= 0) return this; - return this.push({ 'delete': length }); -}; - -Delta.prototype.retain = function (length, attributes) { - if (length <= 0) return this; - var newOp = { retain: length }; - if (attributes != null && typeof attributes === 'object' && Object.keys(attributes).length > 0) { - newOp.attributes = attributes; - } - return this.push(newOp); -}; - -Delta.prototype.push = function (newOp) { - var index = this.ops.length; - var lastOp = this.ops[index - 1]; - newOp = extend(true, {}, newOp); - if (typeof lastOp === 'object') { - if (typeof newOp['delete'] === 'number' && typeof lastOp['delete'] === 'number') { - this.ops[index - 1] = { 'delete': lastOp['delete'] + newOp['delete'] }; - return this; - } - // Since it does not matter if we insert before or after deleting at the same index, - // always prefer to insert first - if (typeof lastOp['delete'] === 'number' && newOp.insert != null) { - index -= 1; - lastOp = this.ops[index - 1]; - if (typeof lastOp !== 'object') { - this.ops.unshift(newOp); - return this; - } - } - if (equal(newOp.attributes, lastOp.attributes)) { - if (typeof newOp.insert === 'string' && typeof lastOp.insert === 'string') { - this.ops[index - 1] = { insert: lastOp.insert + newOp.insert }; - if (typeof newOp.attributes === 'object') this.ops[index - 1].attributes = newOp.attributes - return this; - } else if (typeof newOp.retain === 'number' && typeof lastOp.retain === 'number') { - this.ops[index - 1] = { retain: lastOp.retain + newOp.retain }; - if (typeof newOp.attributes === 'object') this.ops[index - 1].attributes = newOp.attributes - return this; - } - } - } - if (index === this.ops.length) { - this.ops.push(newOp); - } else { - this.ops.splice(index, 0, newOp); - } - return this; -}; - -Delta.prototype.chop = function () { - var lastOp = this.ops[this.ops.length - 1]; - if (lastOp && lastOp.retain && !lastOp.attributes) { - this.ops.pop(); - } - return this; -}; - -Delta.prototype.filter = function (predicate) { - return this.ops.filter(predicate); -}; - -Delta.prototype.forEach = function (predicate) { - this.ops.forEach(predicate); -}; - -Delta.prototype.map = function (predicate) { - return this.ops.map(predicate); -}; - -Delta.prototype.partition = function (predicate) { - var passed = [], failed = []; - this.forEach(function(op) { - var target = predicate(op) ? passed : failed; - target.push(op); - }); - return [passed, failed]; -}; - -Delta.prototype.reduce = function (predicate, initial) { - return this.ops.reduce(predicate, initial); -}; - -Delta.prototype.changeLength = function () { - return this.reduce(function (length, elem) { - if (elem.insert) { - return length + op.length(elem); - } else if (elem.delete) { - return length - elem.delete; - } - return length; - }, 0); -}; - -Delta.prototype.length = function () { - return this.reduce(function (length, elem) { - return length + op.length(elem); - }, 0); -}; - -Delta.prototype.slice = function (start, end) { - start = start || 0; - if (typeof end !== 'number') end = Infinity; - var ops = []; - var iter = op.iterator(this.ops); - var index = 0; - while (index < end && iter.hasNext()) { - var nextOp; - if (index < start) { - nextOp = iter.next(start - index); - } else { - nextOp = iter.next(end - index); - ops.push(nextOp); - } - index += op.length(nextOp); - } - return new Delta(ops); -}; - - -Delta.prototype.compose = function (other) { - var thisIter = op.iterator(this.ops); - var otherIter = op.iterator(other.ops); - var ops = []; - var firstOther = otherIter.peek(); - if (firstOther != null && typeof firstOther.retain === 'number' && firstOther.attributes == null) { - var firstLeft = firstOther.retain; - while (thisIter.peekType() === 'insert' && thisIter.peekLength() <= firstLeft) { - firstLeft -= thisIter.peekLength(); - ops.push(thisIter.next()); - } - if (firstOther.retain - firstLeft > 0) { - otherIter.next(firstOther.retain - firstLeft); - } - } - var delta = new Delta(ops); - while (thisIter.hasNext() || otherIter.hasNext()) { - if (otherIter.peekType() === 'insert') { - delta.push(otherIter.next()); - } else if (thisIter.peekType() === 'delete') { - delta.push(thisIter.next()); - } else { - var length = Math.min(thisIter.peekLength(), otherIter.peekLength()); - var thisOp = thisIter.next(length); - var otherOp = otherIter.next(length); - if (typeof otherOp.retain === 'number') { - var newOp = {}; - if (typeof thisOp.retain === 'number') { - newOp.retain = length; - } else { - newOp.insert = thisOp.insert; - } - // Preserve null when composing with a retain, otherwise remove it for inserts - var attributes = op.attributes.compose(thisOp.attributes, otherOp.attributes, typeof thisOp.retain === 'number'); - if (attributes) newOp.attributes = attributes; - delta.push(newOp); - - // Optimization if rest of other is just retain - if (!otherIter.hasNext() && equal(delta.ops[delta.ops.length - 1], newOp)) { - var rest = new Delta(thisIter.rest()); - return delta.concat(rest).chop(); - } - - // Other op should be delete, we could be an insert or retain - // Insert + delete cancels out - } else if (typeof otherOp['delete'] === 'number' && typeof thisOp.retain === 'number') { - delta.push(otherOp); - } - } - } - return delta.chop(); -}; - -Delta.prototype.concat = function (other) { - var delta = new Delta(this.ops.slice()); - if (other.ops.length > 0) { - delta.push(other.ops[0]); - delta.ops = delta.ops.concat(other.ops.slice(1)); - } - return delta; -}; - -Delta.prototype.diff = function (other, index) { - if (this.ops === other.ops) { - return new Delta(); - } - var strings = [this, other].map(function (delta) { - return delta.map(function (op) { - if (op.insert != null) { - return typeof op.insert === 'string' ? op.insert : NULL_CHARACTER; - } - var prep = (delta === other) ? 'on' : 'with'; - throw new Error('diff() called ' + prep + ' non-document'); - }).join(''); - }); - var delta = new Delta(); - var diffResult = diff(strings[0], strings[1], index); - var thisIter = op.iterator(this.ops); - var otherIter = op.iterator(other.ops); - diffResult.forEach(function (component) { - var length = component[1].length; - while (length > 0) { - var opLength = 0; - switch (component[0]) { - case diff.INSERT: - opLength = Math.min(otherIter.peekLength(), length); - delta.push(otherIter.next(opLength)); - break; - case diff.DELETE: - opLength = Math.min(length, thisIter.peekLength()); - thisIter.next(opLength); - delta['delete'](opLength); - break; - case diff.EQUAL: - opLength = Math.min(thisIter.peekLength(), otherIter.peekLength(), length); - var thisOp = thisIter.next(opLength); - var otherOp = otherIter.next(opLength); - if (equal(thisOp.insert, otherOp.insert)) { - delta.retain(opLength, op.attributes.diff(thisOp.attributes, otherOp.attributes)); - } else { - delta.push(otherOp)['delete'](opLength); - } - break; - } - length -= opLength; - } - }); - return delta.chop(); -}; - -Delta.prototype.eachLine = function (predicate, newline) { - newline = newline || '\n'; - var iter = op.iterator(this.ops); - var line = new Delta(); - var i = 0; - while (iter.hasNext()) { - if (iter.peekType() !== 'insert') return; - var thisOp = iter.peek(); - var start = op.length(thisOp) - iter.peekLength(); - var index = typeof thisOp.insert === 'string' ? - thisOp.insert.indexOf(newline, start) - start : -1; - if (index < 0) { - line.push(iter.next()); - } else if (index > 0) { - line.push(iter.next(index)); - } else { - if (predicate(line, iter.next(1).attributes || {}, i) === false) { - return; - } - i += 1; - line = new Delta(); - } - } - if (line.length() > 0) { - predicate(line, {}, i); - } -}; - -Delta.prototype.transform = function (other, priority) { - priority = !!priority; - if (typeof other === 'number') { - return this.transformPosition(other, priority); - } - var thisIter = op.iterator(this.ops); - var otherIter = op.iterator(other.ops); - var delta = new Delta(); - while (thisIter.hasNext() || otherIter.hasNext()) { - if (thisIter.peekType() === 'insert' && (priority || otherIter.peekType() !== 'insert')) { - delta.retain(op.length(thisIter.next())); - } else if (otherIter.peekType() === 'insert') { - delta.push(otherIter.next()); - } else { - var length = Math.min(thisIter.peekLength(), otherIter.peekLength()); - var thisOp = thisIter.next(length); - var otherOp = otherIter.next(length); - if (thisOp['delete']) { - // Our delete either makes their delete redundant or removes their retain - continue; - } else if (otherOp['delete']) { - delta.push(otherOp); - } else { - // We retain either their retain or insert - delta.retain(length, op.attributes.transform(thisOp.attributes, otherOp.attributes, priority)); - } - } - } - return delta.chop(); -}; - -Delta.prototype.transformPosition = function (index, priority) { - priority = !!priority; - var thisIter = op.iterator(this.ops); - var offset = 0; - while (thisIter.hasNext() && offset <= index) { - var length = thisIter.peekLength(); - var nextType = thisIter.peekType(); - thisIter.next(); - if (nextType === 'delete') { - index -= Math.min(length, index - offset); - continue; - } else if (nextType === 'insert' && (offset < index || !priority)) { - index += length; - } - offset += length; - } - return index; -}; - - -module.exports = Delta; - - -/***/ }), -/* 3 */ -/***/ (function(module, exports) { - -'use strict'; - -var hasOwn = Object.prototype.hasOwnProperty; -var toStr = Object.prototype.toString; -var defineProperty = Object.defineProperty; -var gOPD = Object.getOwnPropertyDescriptor; - -var isArray = function isArray(arr) { - if (typeof Array.isArray === 'function') { - return Array.isArray(arr); - } - - return toStr.call(arr) === '[object Array]'; -}; - -var isPlainObject = function isPlainObject(obj) { - if (!obj || toStr.call(obj) !== '[object Object]') { - return false; - } - - var hasOwnConstructor = hasOwn.call(obj, 'constructor'); - var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); - // Not own constructor property must be Object - if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - var key; - for (key in obj) { /**/ } - - return typeof key === 'undefined' || hasOwn.call(obj, key); -}; - -// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target -var setProperty = function setProperty(target, options) { - if (defineProperty && options.name === '__proto__') { - defineProperty(target, options.name, { - enumerable: true, - configurable: true, - value: options.newValue, - writable: true - }); - } else { - target[options.name] = options.newValue; - } -}; - -// Return undefined instead of __proto__ if '__proto__' is not an own property -var getProperty = function getProperty(obj, name) { - if (name === '__proto__') { - if (!hasOwn.call(obj, name)) { - return void 0; - } else if (gOPD) { - // In early versions of node, obj['__proto__'] is buggy when obj has - // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. - return gOPD(obj, name).value; - } - } - - return obj[name]; -}; - -module.exports = function extend() { - var options, name, src, copy, copyIsArray, clone; - var target = arguments[0]; - var i = 1; - var length = arguments.length; - var deep = false; - - // Handle a deep copy situation - if (typeof target === 'boolean') { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { - target = {}; - } - - for (; i < length; ++i) { - options = arguments[i]; - // Only deal with non-null/undefined values - if (options != null) { - // Extend the base object - for (name in options) { - src = getProperty(target, name); - copy = getProperty(options, name); - - // Prevent never-ending loop - if (target !== copy) { - // Recurse if we're merging plain objects or arrays - if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && isArray(src) ? src : []; - } else { - clone = src && isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); - - // Don't bring in undefined values - } else if (typeof copy !== 'undefined') { - setProperty(target, { name: name, newValue: copy }); - } - } - } - } - } - - // Return the modified object - return target; -}; - - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.BlockEmbed = exports.bubbleFormats = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _extend = __webpack_require__(3); - -var _extend2 = _interopRequireDefault(_extend); - -var _quillDelta = __webpack_require__(2); - -var _quillDelta2 = _interopRequireDefault(_quillDelta); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _break = __webpack_require__(16); - -var _break2 = _interopRequireDefault(_break); - -var _inline = __webpack_require__(6); - -var _inline2 = _interopRequireDefault(_inline); - -var _text = __webpack_require__(7); - -var _text2 = _interopRequireDefault(_text); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var NEWLINE_LENGTH = 1; - -var BlockEmbed = function (_Parchment$Embed) { - _inherits(BlockEmbed, _Parchment$Embed); - - function BlockEmbed() { - _classCallCheck(this, BlockEmbed); - - return _possibleConstructorReturn(this, (BlockEmbed.__proto__ || Object.getPrototypeOf(BlockEmbed)).apply(this, arguments)); - } - - _createClass(BlockEmbed, [{ - key: 'attach', - value: function attach() { - _get(BlockEmbed.prototype.__proto__ || Object.getPrototypeOf(BlockEmbed.prototype), 'attach', this).call(this); - this.attributes = new _parchment2.default.Attributor.Store(this.domNode); - } - }, { - key: 'delta', - value: function delta() { - return new _quillDelta2.default().insert(this.value(), (0, _extend2.default)(this.formats(), this.attributes.values())); - } - }, { - key: 'format', - value: function format(name, value) { - var attribute = _parchment2.default.query(name, _parchment2.default.Scope.BLOCK_ATTRIBUTE); - if (attribute != null) { - this.attributes.attribute(attribute, value); - } - } - }, { - key: 'formatAt', - value: function formatAt(index, length, name, value) { - this.format(name, value); - } - }, { - key: 'insertAt', - value: function insertAt(index, value, def) { - if (typeof value === 'string' && value.endsWith('\n')) { - var block = _parchment2.default.create(Block.blotName); - this.parent.insertBefore(block, index === 0 ? this : this.next); - block.insertAt(0, value.slice(0, -1)); - } else { - _get(BlockEmbed.prototype.__proto__ || Object.getPrototypeOf(BlockEmbed.prototype), 'insertAt', this).call(this, index, value, def); - } - } - }]); - - return BlockEmbed; -}(_parchment2.default.Embed); - -BlockEmbed.scope = _parchment2.default.Scope.BLOCK_BLOT; -// It is important for cursor behavior BlockEmbeds use tags that are block level elements - - -var Block = function (_Parchment$Block) { - _inherits(Block, _Parchment$Block); - - function Block(domNode) { - _classCallCheck(this, Block); - - var _this2 = _possibleConstructorReturn(this, (Block.__proto__ || Object.getPrototypeOf(Block)).call(this, domNode)); - - _this2.cache = {}; - return _this2; - } - - _createClass(Block, [{ - key: 'delta', - value: function delta() { - if (this.cache.delta == null) { - this.cache.delta = this.descendants(_parchment2.default.Leaf).reduce(function (delta, leaf) { - if (leaf.length() === 0) { - return delta; - } else { - return delta.insert(leaf.value(), bubbleFormats(leaf)); - } - }, new _quillDelta2.default()).insert('\n', bubbleFormats(this)); - } - return this.cache.delta; - } - }, { - key: 'deleteAt', - value: function deleteAt(index, length) { - _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'deleteAt', this).call(this, index, length); - this.cache = {}; - } - }, { - key: 'formatAt', - value: function formatAt(index, length, name, value) { - if (length <= 0) return; - if (_parchment2.default.query(name, _parchment2.default.Scope.BLOCK)) { - if (index + length === this.length()) { - this.format(name, value); - } - } else { - _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'formatAt', this).call(this, index, Math.min(length, this.length() - index - 1), name, value); - } - this.cache = {}; - } - }, { - key: 'insertAt', - value: function insertAt(index, value, def) { - if (def != null) return _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'insertAt', this).call(this, index, value, def); - if (value.length === 0) return; - var lines = value.split('\n'); - var text = lines.shift(); - if (text.length > 0) { - if (index < this.length() - 1 || this.children.tail == null) { - _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'insertAt', this).call(this, Math.min(index, this.length() - 1), text); - } else { - this.children.tail.insertAt(this.children.tail.length(), text); - } - this.cache = {}; - } - var block = this; - lines.reduce(function (index, line) { - block = block.split(index, true); - block.insertAt(0, line); - return line.length; - }, index + text.length); - } - }, { - key: 'insertBefore', - value: function insertBefore(blot, ref) { - var head = this.children.head; - _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'insertBefore', this).call(this, blot, ref); - if (head instanceof _break2.default) { - head.remove(); - } - this.cache = {}; - } - }, { - key: 'length', - value: function length() { - if (this.cache.length == null) { - this.cache.length = _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'length', this).call(this) + NEWLINE_LENGTH; - } - return this.cache.length; - } - }, { - key: 'moveChildren', - value: function moveChildren(target, ref) { - _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'moveChildren', this).call(this, target, ref); - this.cache = {}; - } - }, { - key: 'optimize', - value: function optimize(context) { - _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'optimize', this).call(this, context); - this.cache = {}; - } - }, { - key: 'path', - value: function path(index) { - return _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'path', this).call(this, index, true); - } - }, { - key: 'removeChild', - value: function removeChild(child) { - _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'removeChild', this).call(this, child); - this.cache = {}; - } - }, { - key: 'split', - value: function split(index) { - var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - if (force && (index === 0 || index >= this.length() - NEWLINE_LENGTH)) { - var clone = this.clone(); - if (index === 0) { - this.parent.insertBefore(clone, this); - return this; - } else { - this.parent.insertBefore(clone, this.next); - return clone; - } - } else { - var next = _get(Block.prototype.__proto__ || Object.getPrototypeOf(Block.prototype), 'split', this).call(this, index, force); - this.cache = {}; - return next; - } - } - }]); - - return Block; -}(_parchment2.default.Block); - -Block.blotName = 'block'; -Block.tagName = 'P'; -Block.defaultChild = 'break'; -Block.allowedChildren = [_inline2.default, _parchment2.default.Embed, _text2.default]; - -function bubbleFormats(blot) { - var formats = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (blot == null) return formats; - if (typeof blot.formats === 'function') { - formats = (0, _extend2.default)(formats, blot.formats()); - } - if (blot.parent == null || blot.parent.blotName == 'scroll' || blot.parent.statics.scope !== blot.statics.scope) { - return formats; - } - return bubbleFormats(blot.parent, formats); -} - -exports.bubbleFormats = bubbleFormats; -exports.BlockEmbed = BlockEmbed; -exports.default = Block; - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.overload = exports.expandConfig = undefined; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -__webpack_require__(50); - -var _quillDelta = __webpack_require__(2); - -var _quillDelta2 = _interopRequireDefault(_quillDelta); - -var _editor = __webpack_require__(14); - -var _editor2 = _interopRequireDefault(_editor); - -var _emitter3 = __webpack_require__(8); - -var _emitter4 = _interopRequireDefault(_emitter3); - -var _module = __webpack_require__(9); - -var _module2 = _interopRequireDefault(_module); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _selection = __webpack_require__(15); - -var _selection2 = _interopRequireDefault(_selection); - -var _extend = __webpack_require__(3); - -var _extend2 = _interopRequireDefault(_extend); - -var _logger = __webpack_require__(10); - -var _logger2 = _interopRequireDefault(_logger); - -var _theme = __webpack_require__(34); - -var _theme2 = _interopRequireDefault(_theme); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var debug = (0, _logger2.default)('quill'); - -var Quill = function () { - _createClass(Quill, null, [{ - key: 'debug', - value: function debug(limit) { - if (limit === true) { - limit = 'log'; - } - _logger2.default.level(limit); - } - }, { - key: 'find', - value: function find(node) { - return node.__quill || _parchment2.default.find(node); - } - }, { - key: 'import', - value: function _import(name) { - if (this.imports[name] == null) { - debug.error('Cannot import ' + name + '. Are you sure it was registered?'); - } - return this.imports[name]; - } - }, { - key: 'register', - value: function register(path, target) { - var _this = this; - - var overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - if (typeof path !== 'string') { - var name = path.attrName || path.blotName; - if (typeof name === 'string') { - // register(Blot | Attributor, overwrite) - this.register('formats/' + name, path, target); - } else { - Object.keys(path).forEach(function (key) { - _this.register(key, path[key], target); - }); - } - } else { - if (this.imports[path] != null && !overwrite) { - debug.warn('Overwriting ' + path + ' with', target); - } - this.imports[path] = target; - if ((path.startsWith('blots/') || path.startsWith('formats/')) && target.blotName !== 'abstract') { - _parchment2.default.register(target); - } else if (path.startsWith('modules') && typeof target.register === 'function') { - target.register(); - } - } - } - }]); - - function Quill(container) { - var _this2 = this; - - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - _classCallCheck(this, Quill); - - this.options = expandConfig(container, options); - this.container = this.options.container; - if (this.container == null) { - return debug.error('Invalid Quill container', container); - } - if (this.options.debug) { - Quill.debug(this.options.debug); - } - var html = this.container.innerHTML.trim(); - this.container.classList.add('ql-container'); - this.container.innerHTML = ''; - this.container.__quill = this; - this.root = this.addContainer('ql-editor'); - this.root.classList.add('ql-blank'); - this.root.setAttribute('data-gramm', false); - this.scrollingContainer = this.options.scrollingContainer || this.root; - this.emitter = new _emitter4.default(); - this.scroll = _parchment2.default.create(this.root, { - emitter: this.emitter, - whitelist: this.options.formats - }); - this.editor = new _editor2.default(this.scroll); - this.selection = new _selection2.default(this.scroll, this.emitter); - this.theme = new this.options.theme(this, this.options); - this.keyboard = this.theme.addModule('keyboard'); - this.clipboard = this.theme.addModule('clipboard'); - this.history = this.theme.addModule('history'); - this.theme.init(); - this.emitter.on(_emitter4.default.events.EDITOR_CHANGE, function (type) { - if (type === _emitter4.default.events.TEXT_CHANGE) { - _this2.root.classList.toggle('ql-blank', _this2.editor.isBlank()); - } - }); - this.emitter.on(_emitter4.default.events.SCROLL_UPDATE, function (source, mutations) { - var range = _this2.selection.lastRange; - var index = range && range.length === 0 ? range.index : undefined; - modify.call(_this2, function () { - return _this2.editor.update(null, mutations, index); - }, source); - }); - var contents = this.clipboard.convert('
' + html + '


'); - this.setContents(contents); - this.history.clear(); - if (this.options.placeholder) { - this.root.setAttribute('data-placeholder', this.options.placeholder); - } - if (this.options.readOnly) { - this.disable(); - } - } - - _createClass(Quill, [{ - key: 'addContainer', - value: function addContainer(container) { - var refNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - - if (typeof container === 'string') { - var className = container; - container = document.createElement('div'); - container.classList.add(className); - } - this.container.insertBefore(container, refNode); - return container; - } - }, { - key: 'blur', - value: function blur() { - this.selection.setRange(null); - } - }, { - key: 'deleteText', - value: function deleteText(index, length, source) { - var _this3 = this; - - var _overload = overload(index, length, source); - - var _overload2 = _slicedToArray(_overload, 4); - - index = _overload2[0]; - length = _overload2[1]; - source = _overload2[3]; - - return modify.call(this, function () { - return _this3.editor.deleteText(index, length); - }, source, index, -1 * length); - } - }, { - key: 'disable', - value: function disable() { - this.enable(false); - } - }, { - key: 'enable', - value: function enable() { - var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - - this.scroll.enable(enabled); - this.container.classList.toggle('ql-disabled', !enabled); - } - }, { - key: 'focus', - value: function focus() { - var scrollTop = this.scrollingContainer.scrollTop; - this.selection.focus(); - this.scrollingContainer.scrollTop = scrollTop; - this.scrollIntoView(); - } - }, { - key: 'format', - value: function format(name, value) { - var _this4 = this; - - var source = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _emitter4.default.sources.API; - - return modify.call(this, function () { - var range = _this4.getSelection(true); - var change = new _quillDelta2.default(); - if (range == null) { - return change; - } else if (_parchment2.default.query(name, _parchment2.default.Scope.BLOCK)) { - change = _this4.editor.formatLine(range.index, range.length, _defineProperty({}, name, value)); - } else if (range.length === 0) { - _this4.selection.format(name, value); - return change; - } else { - change = _this4.editor.formatText(range.index, range.length, _defineProperty({}, name, value)); - } - _this4.setSelection(range, _emitter4.default.sources.SILENT); - return change; - }, source); - } - }, { - key: 'formatLine', - value: function formatLine(index, length, name, value, source) { - var _this5 = this; - - var formats = void 0; - - var _overload3 = overload(index, length, name, value, source); - - var _overload4 = _slicedToArray(_overload3, 4); - - index = _overload4[0]; - length = _overload4[1]; - formats = _overload4[2]; - source = _overload4[3]; - - return modify.call(this, function () { - return _this5.editor.formatLine(index, length, formats); - }, source, index, 0); - } - }, { - key: 'formatText', - value: function formatText(index, length, name, value, source) { - var _this6 = this; - - var formats = void 0; - - var _overload5 = overload(index, length, name, value, source); - - var _overload6 = _slicedToArray(_overload5, 4); - - index = _overload6[0]; - length = _overload6[1]; - formats = _overload6[2]; - source = _overload6[3]; - - return modify.call(this, function () { - return _this6.editor.formatText(index, length, formats); - }, source, index, 0); - } - }, { - key: 'getBounds', - value: function getBounds(index) { - var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - var bounds = void 0; - if (typeof index === 'number') { - bounds = this.selection.getBounds(index, length); - } else { - bounds = this.selection.getBounds(index.index, index.length); - } - var containerBounds = this.container.getBoundingClientRect(); - return { - bottom: bounds.bottom - containerBounds.top, - height: bounds.height, - left: bounds.left - containerBounds.left, - right: bounds.right - containerBounds.left, - top: bounds.top - containerBounds.top, - width: bounds.width - }; - } - }, { - key: 'getContents', - value: function getContents() { - var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getLength() - index; - - var _overload7 = overload(index, length); - - var _overload8 = _slicedToArray(_overload7, 2); - - index = _overload8[0]; - length = _overload8[1]; - - return this.editor.getContents(index, length); - } - }, { - key: 'getFormat', - value: function getFormat() { - var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getSelection(true); - var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - if (typeof index === 'number') { - return this.editor.getFormat(index, length); - } else { - return this.editor.getFormat(index.index, index.length); - } - } - }, { - key: 'getIndex', - value: function getIndex(blot) { - return blot.offset(this.scroll); - } - }, { - key: 'getLength', - value: function getLength() { - return this.scroll.length(); - } - }, { - key: 'getLeaf', - value: function getLeaf(index) { - return this.scroll.leaf(index); - } - }, { - key: 'getLine', - value: function getLine(index) { - return this.scroll.line(index); - } - }, { - key: 'getLines', - value: function getLines() { - var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Number.MAX_VALUE; - - if (typeof index !== 'number') { - return this.scroll.lines(index.index, index.length); - } else { - return this.scroll.lines(index, length); - } - } - }, { - key: 'getModule', - value: function getModule(name) { - return this.theme.modules[name]; - } - }, { - key: 'getSelection', - value: function getSelection() { - var focus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - - if (focus) this.focus(); - this.update(); // Make sure we access getRange with editor in consistent state - return this.selection.getRange()[0]; - } - }, { - key: 'getText', - value: function getText() { - var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getLength() - index; - - var _overload9 = overload(index, length); - - var _overload10 = _slicedToArray(_overload9, 2); - - index = _overload10[0]; - length = _overload10[1]; - - return this.editor.getText(index, length); - } - }, { - key: 'hasFocus', - value: function hasFocus() { - return this.selection.hasFocus(); - } - }, { - key: 'insertEmbed', - value: function insertEmbed(index, embed, value) { - var _this7 = this; - - var source = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : Quill.sources.API; - - return modify.call(this, function () { - return _this7.editor.insertEmbed(index, embed, value); - }, source, index); - } - }, { - key: 'insertText', - value: function insertText(index, text, name, value, source) { - var _this8 = this; - - var formats = void 0; - - var _overload11 = overload(index, 0, name, value, source); - - var _overload12 = _slicedToArray(_overload11, 4); - - index = _overload12[0]; - formats = _overload12[2]; - source = _overload12[3]; - - return modify.call(this, function () { - return _this8.editor.insertText(index, text, formats); - }, source, index, text.length); - } - }, { - key: 'isEnabled', - value: function isEnabled() { - return !this.container.classList.contains('ql-disabled'); - } - }, { - key: 'off', - value: function off() { - return this.emitter.off.apply(this.emitter, arguments); - } - }, { - key: 'on', - value: function on() { - return this.emitter.on.apply(this.emitter, arguments); - } - }, { - key: 'once', - value: function once() { - return this.emitter.once.apply(this.emitter, arguments); - } - }, { - key: 'pasteHTML', - value: function pasteHTML(index, html, source) { - this.clipboard.dangerouslyPasteHTML(index, html, source); - } - }, { - key: 'removeFormat', - value: function removeFormat(index, length, source) { - var _this9 = this; - - var _overload13 = overload(index, length, source); - - var _overload14 = _slicedToArray(_overload13, 4); - - index = _overload14[0]; - length = _overload14[1]; - source = _overload14[3]; - - return modify.call(this, function () { - return _this9.editor.removeFormat(index, length); - }, source, index); - } - }, { - key: 'scrollIntoView', - value: function scrollIntoView() { - this.selection.scrollIntoView(this.scrollingContainer); - } - }, { - key: 'setContents', - value: function setContents(delta) { - var _this10 = this; - - var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _emitter4.default.sources.API; - - return modify.call(this, function () { - delta = new _quillDelta2.default(delta); - var length = _this10.getLength(); - var deleted = _this10.editor.deleteText(0, length); - var applied = _this10.editor.applyDelta(delta); - var lastOp = applied.ops[applied.ops.length - 1]; - if (lastOp != null && typeof lastOp.insert === 'string' && lastOp.insert[lastOp.insert.length - 1] === '\n') { - _this10.editor.deleteText(_this10.getLength() - 1, 1); - applied.delete(1); - } - var ret = deleted.compose(applied); - return ret; - }, source); - } - }, { - key: 'setSelection', - value: function setSelection(index, length, source) { - if (index == null) { - this.selection.setRange(null, length || Quill.sources.API); - } else { - var _overload15 = overload(index, length, source); - - var _overload16 = _slicedToArray(_overload15, 4); - - index = _overload16[0]; - length = _overload16[1]; - source = _overload16[3]; - - this.selection.setRange(new _selection.Range(index, length), source); - if (source !== _emitter4.default.sources.SILENT) { - this.selection.scrollIntoView(this.scrollingContainer); - } - } - } - }, { - key: 'setText', - value: function setText(text) { - var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _emitter4.default.sources.API; - - var delta = new _quillDelta2.default().insert(text); - return this.setContents(delta, source); - } - }, { - key: 'update', - value: function update() { - var source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _emitter4.default.sources.USER; - - var change = this.scroll.update(source); // Will update selection before selection.update() does if text changes - this.selection.update(source); - return change; - } - }, { - key: 'updateContents', - value: function updateContents(delta) { - var _this11 = this; - - var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _emitter4.default.sources.API; - - return modify.call(this, function () { - delta = new _quillDelta2.default(delta); - return _this11.editor.applyDelta(delta, source); - }, source, true); - } - }]); - - return Quill; -}(); - -Quill.DEFAULTS = { - bounds: null, - formats: null, - modules: {}, - placeholder: '', - readOnly: false, - scrollingContainer: null, - strict: true, - theme: 'default' -}; -Quill.events = _emitter4.default.events; -Quill.sources = _emitter4.default.sources; -// eslint-disable-next-line no-undef -Quill.version = false ? 'dev' : "1.3.7"; - -Quill.imports = { - 'delta': _quillDelta2.default, - 'parchment': _parchment2.default, - 'core/module': _module2.default, - 'core/theme': _theme2.default -}; - -function expandConfig(container, userConfig) { - userConfig = (0, _extend2.default)(true, { - container: container, - modules: { - clipboard: true, - keyboard: true, - history: true - } - }, userConfig); - if (!userConfig.theme || userConfig.theme === Quill.DEFAULTS.theme) { - userConfig.theme = _theme2.default; - } else { - userConfig.theme = Quill.import('themes/' + userConfig.theme); - if (userConfig.theme == null) { - throw new Error('Invalid theme ' + userConfig.theme + '. Did you register it?'); - } - } - var themeConfig = (0, _extend2.default)(true, {}, userConfig.theme.DEFAULTS); - [themeConfig, userConfig].forEach(function (config) { - config.modules = config.modules || {}; - Object.keys(config.modules).forEach(function (module) { - if (config.modules[module] === true) { - config.modules[module] = {}; - } - }); - }); - var moduleNames = Object.keys(themeConfig.modules).concat(Object.keys(userConfig.modules)); - var moduleConfig = moduleNames.reduce(function (config, name) { - var moduleClass = Quill.import('modules/' + name); - if (moduleClass == null) { - debug.error('Cannot load ' + name + ' module. Are you sure you registered it?'); - } else { - config[name] = moduleClass.DEFAULTS || {}; - } - return config; - }, {}); - // Special case toolbar shorthand - if (userConfig.modules != null && userConfig.modules.toolbar && userConfig.modules.toolbar.constructor !== Object) { - userConfig.modules.toolbar = { - container: userConfig.modules.toolbar - }; - } - userConfig = (0, _extend2.default)(true, {}, Quill.DEFAULTS, { modules: moduleConfig }, themeConfig, userConfig); - ['bounds', 'container', 'scrollingContainer'].forEach(function (key) { - if (typeof userConfig[key] === 'string') { - userConfig[key] = document.querySelector(userConfig[key]); - } - }); - userConfig.modules = Object.keys(userConfig.modules).reduce(function (config, name) { - if (userConfig.modules[name]) { - config[name] = userConfig.modules[name]; - } - return config; - }, {}); - return userConfig; -} - -// Handle selection preservation and TEXT_CHANGE emission -// common to modification APIs -function modify(modifier, source, index, shift) { - if (this.options.strict && !this.isEnabled() && source === _emitter4.default.sources.USER) { - return new _quillDelta2.default(); - } - var range = index == null ? null : this.getSelection(); - var oldDelta = this.editor.delta; - var change = modifier(); - if (range != null) { - if (index === true) index = range.index; - if (shift == null) { - range = shiftRange(range, change, source); - } else if (shift !== 0) { - range = shiftRange(range, index, shift, source); - } - this.setSelection(range, _emitter4.default.sources.SILENT); - } - if (change.length() > 0) { - var _emitter; - - var args = [_emitter4.default.events.TEXT_CHANGE, change, oldDelta, source]; - (_emitter = this.emitter).emit.apply(_emitter, [_emitter4.default.events.EDITOR_CHANGE].concat(args)); - if (source !== _emitter4.default.sources.SILENT) { - var _emitter2; - - (_emitter2 = this.emitter).emit.apply(_emitter2, args); - } - } - return change; -} - -function overload(index, length, name, value, source) { - var formats = {}; - if (typeof index.index === 'number' && typeof index.length === 'number') { - // Allow for throwaway end (used by insertText/insertEmbed) - if (typeof length !== 'number') { - source = value, value = name, name = length, length = index.length, index = index.index; - } else { - length = index.length, index = index.index; - } - } else if (typeof length !== 'number') { - source = value, value = name, name = length, length = 0; - } - // Handle format being object, two format name/value strings or excluded - if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object') { - formats = name; - source = value; - } else if (typeof name === 'string') { - if (value != null) { - formats[name] = value; - } else { - source = name; - } - } - // Handle optional source - source = source || _emitter4.default.sources.API; - return [index, length, formats, source]; -} - -function shiftRange(range, index, length, source) { - if (range == null) return null; - var start = void 0, - end = void 0; - if (index instanceof _quillDelta2.default) { - var _map = [range.index, range.index + range.length].map(function (pos) { - return index.transformPosition(pos, source !== _emitter4.default.sources.USER); - }); - - var _map2 = _slicedToArray(_map, 2); - - start = _map2[0]; - end = _map2[1]; - } else { - var _map3 = [range.index, range.index + range.length].map(function (pos) { - if (pos < index || pos === index && source === _emitter4.default.sources.USER) return pos; - if (length >= 0) { - return pos + length; - } else { - return Math.max(index, pos + length); - } - }); - - var _map4 = _slicedToArray(_map3, 2); - - start = _map4[0]; - end = _map4[1]; - } - return new _selection.Range(start, end - start); -} - -exports.expandConfig = expandConfig; -exports.overload = overload; -exports.default = Quill; - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _text = __webpack_require__(7); - -var _text2 = _interopRequireDefault(_text); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Inline = function (_Parchment$Inline) { - _inherits(Inline, _Parchment$Inline); - - function Inline() { - _classCallCheck(this, Inline); - - return _possibleConstructorReturn(this, (Inline.__proto__ || Object.getPrototypeOf(Inline)).apply(this, arguments)); - } - - _createClass(Inline, [{ - key: 'formatAt', - value: function formatAt(index, length, name, value) { - if (Inline.compare(this.statics.blotName, name) < 0 && _parchment2.default.query(name, _parchment2.default.Scope.BLOT)) { - var blot = this.isolate(index, length); - if (value) { - blot.wrap(name, value); - } - } else { - _get(Inline.prototype.__proto__ || Object.getPrototypeOf(Inline.prototype), 'formatAt', this).call(this, index, length, name, value); - } - } - }, { - key: 'optimize', - value: function optimize(context) { - _get(Inline.prototype.__proto__ || Object.getPrototypeOf(Inline.prototype), 'optimize', this).call(this, context); - if (this.parent instanceof Inline && Inline.compare(this.statics.blotName, this.parent.statics.blotName) > 0) { - var parent = this.parent.isolate(this.offset(), this.length()); - this.moveChildren(parent); - parent.wrap(this); - } - } - }], [{ - key: 'compare', - value: function compare(self, other) { - var selfIndex = Inline.order.indexOf(self); - var otherIndex = Inline.order.indexOf(other); - if (selfIndex >= 0 || otherIndex >= 0) { - return selfIndex - otherIndex; - } else if (self === other) { - return 0; - } else if (self < other) { - return -1; - } else { - return 1; - } - } - }]); - - return Inline; -}(_parchment2.default.Inline); - -Inline.allowedChildren = [Inline, _parchment2.default.Embed, _text2.default]; -// Lower index means deeper in the DOM tree, since not found (-1) is for embeds -Inline.order = ['cursor', 'inline', // Must be lower -'underline', 'strike', 'italic', 'bold', 'script', 'link', 'code' // Must be higher -]; - -exports.default = Inline; - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var TextBlot = function (_Parchment$Text) { - _inherits(TextBlot, _Parchment$Text); - - function TextBlot() { - _classCallCheck(this, TextBlot); - - return _possibleConstructorReturn(this, (TextBlot.__proto__ || Object.getPrototypeOf(TextBlot)).apply(this, arguments)); - } - - return TextBlot; -}(_parchment2.default.Text); - -exports.default = TextBlot; - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _eventemitter = __webpack_require__(54); - -var _eventemitter2 = _interopRequireDefault(_eventemitter); - -var _logger = __webpack_require__(10); - -var _logger2 = _interopRequireDefault(_logger); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var debug = (0, _logger2.default)('quill:events'); - -var EVENTS = ['selectionchange', 'mousedown', 'mouseup', 'click']; - -EVENTS.forEach(function (eventName) { - document.addEventListener(eventName, function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - [].slice.call(document.querySelectorAll('.ql-container')).forEach(function (node) { - // TODO use WeakMap - if (node.__quill && node.__quill.emitter) { - var _node$__quill$emitter; - - (_node$__quill$emitter = node.__quill.emitter).handleDOM.apply(_node$__quill$emitter, args); - } - }); - }); -}); - -var Emitter = function (_EventEmitter) { - _inherits(Emitter, _EventEmitter); - - function Emitter() { - _classCallCheck(this, Emitter); - - var _this = _possibleConstructorReturn(this, (Emitter.__proto__ || Object.getPrototypeOf(Emitter)).call(this)); - - _this.listeners = {}; - _this.on('error', debug.error); - return _this; - } - - _createClass(Emitter, [{ - key: 'emit', - value: function emit() { - debug.log.apply(debug, arguments); - _get(Emitter.prototype.__proto__ || Object.getPrototypeOf(Emitter.prototype), 'emit', this).apply(this, arguments); - } - }, { - key: 'handleDOM', - value: function handleDOM(event) { - for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { - args[_key2 - 1] = arguments[_key2]; - } - - (this.listeners[event.type] || []).forEach(function (_ref) { - var node = _ref.node, - handler = _ref.handler; - - if (event.target === node || node.contains(event.target)) { - handler.apply(undefined, [event].concat(args)); - } - }); - } - }, { - key: 'listenDOM', - value: function listenDOM(eventName, node, handler) { - if (!this.listeners[eventName]) { - this.listeners[eventName] = []; - } - this.listeners[eventName].push({ node: node, handler: handler }); - } - }]); - - return Emitter; -}(_eventemitter2.default); - -Emitter.events = { - EDITOR_CHANGE: 'editor-change', - SCROLL_BEFORE_UPDATE: 'scroll-before-update', - SCROLL_OPTIMIZE: 'scroll-optimize', - SCROLL_UPDATE: 'scroll-update', - SELECTION_CHANGE: 'selection-change', - TEXT_CHANGE: 'text-change' -}; -Emitter.sources = { - API: 'api', - SILENT: 'silent', - USER: 'user' -}; - -exports.default = Emitter; - -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Module = function Module(quill) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - _classCallCheck(this, Module); - - this.quill = quill; - this.options = options; -}; - -Module.DEFAULTS = {}; - -exports.default = Module; - -/***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var levels = ['error', 'warn', 'log', 'info']; -var level = 'warn'; - -function debug(method) { - if (levels.indexOf(method) <= levels.indexOf(level)) { - var _console; - - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - (_console = console)[method].apply(_console, args); // eslint-disable-line no-console - } -} - -function namespace(ns) { - return levels.reduce(function (logger, method) { - logger[method] = debug.bind(console, method, ns); - return logger; - }, {}); -} - -debug.level = namespace.level = function (newLevel) { - level = newLevel; -}; - -exports.default = namespace; - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -var pSlice = Array.prototype.slice; -var objectKeys = __webpack_require__(52); -var isArguments = __webpack_require__(53); - -var deepEqual = module.exports = function (actual, expected, opts) { - if (!opts) opts = {}; - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') { - return opts.strict ? actual === expected : actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected, opts); - } -} - -function isUndefinedOrNull(value) { - return value === null || value === undefined; -} - -function isBuffer (x) { - if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false; - if (typeof x.copy !== 'function' || typeof x.slice !== 'function') { - return false; - } - if (x.length > 0 && typeof x[0] !== 'number') return false; - return true; -} - -function objEquiv(a, b, opts) { - var i, key; - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return deepEqual(a, b, opts); - } - if (isBuffer(a)) { - if (!isBuffer(b)) { - return false; - } - if (a.length !== b.length) return false; - for (i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false; - } - return true; - } - try { - var ka = objectKeys(a), - kb = objectKeys(b); - } catch (e) {//happens when one is a string literal and the other isn't - return false; - } - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!deepEqual(a[key], b[key], opts)) return false; - } - return typeof a === typeof b; -} - - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var Registry = __webpack_require__(1); -var Attributor = /** @class */ (function () { - function Attributor(attrName, keyName, options) { - if (options === void 0) { options = {}; } - this.attrName = attrName; - this.keyName = keyName; - var attributeBit = Registry.Scope.TYPE & Registry.Scope.ATTRIBUTE; - if (options.scope != null) { - // Ignore type bits, force attribute bit - this.scope = (options.scope & Registry.Scope.LEVEL) | attributeBit; - } - else { - this.scope = Registry.Scope.ATTRIBUTE; - } - if (options.whitelist != null) - this.whitelist = options.whitelist; - } - Attributor.keys = function (node) { - return [].map.call(node.attributes, function (item) { - return item.name; - }); - }; - Attributor.prototype.add = function (node, value) { - if (!this.canAdd(node, value)) - return false; - node.setAttribute(this.keyName, value); - return true; - }; - Attributor.prototype.canAdd = function (node, value) { - var match = Registry.query(node, Registry.Scope.BLOT & (this.scope | Registry.Scope.TYPE)); - if (match == null) - return false; - if (this.whitelist == null) - return true; - if (typeof value === 'string') { - return this.whitelist.indexOf(value.replace(/["']/g, '')) > -1; - } - else { - return this.whitelist.indexOf(value) > -1; - } - }; - Attributor.prototype.remove = function (node) { - node.removeAttribute(this.keyName); - }; - Attributor.prototype.value = function (node) { - var value = node.getAttribute(this.keyName); - if (this.canAdd(node, value) && value) { - return value; - } - return ''; - }; - return Attributor; -}()); -exports.default = Attributor; - - -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.Code = undefined; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _quillDelta = __webpack_require__(2); - -var _quillDelta2 = _interopRequireDefault(_quillDelta); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _block = __webpack_require__(4); - -var _block2 = _interopRequireDefault(_block); - -var _inline = __webpack_require__(6); - -var _inline2 = _interopRequireDefault(_inline); - -var _text = __webpack_require__(7); - -var _text2 = _interopRequireDefault(_text); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Code = function (_Inline) { - _inherits(Code, _Inline); - - function Code() { - _classCallCheck(this, Code); - - return _possibleConstructorReturn(this, (Code.__proto__ || Object.getPrototypeOf(Code)).apply(this, arguments)); - } - - return Code; -}(_inline2.default); - -Code.blotName = 'code'; -Code.tagName = 'CODE'; - -var CodeBlock = function (_Block) { - _inherits(CodeBlock, _Block); - - function CodeBlock() { - _classCallCheck(this, CodeBlock); - - return _possibleConstructorReturn(this, (CodeBlock.__proto__ || Object.getPrototypeOf(CodeBlock)).apply(this, arguments)); - } - - _createClass(CodeBlock, [{ - key: 'delta', - value: function delta() { - var _this3 = this; - - var text = this.domNode.textContent; - if (text.endsWith('\n')) { - // Should always be true - text = text.slice(0, -1); - } - return text.split('\n').reduce(function (delta, frag) { - return delta.insert(frag).insert('\n', _this3.formats()); - }, new _quillDelta2.default()); - } - }, { - key: 'format', - value: function format(name, value) { - if (name === this.statics.blotName && value) return; - - var _descendant = this.descendant(_text2.default, this.length() - 1), - _descendant2 = _slicedToArray(_descendant, 1), - text = _descendant2[0]; - - if (text != null) { - text.deleteAt(text.length() - 1, 1); - } - _get(CodeBlock.prototype.__proto__ || Object.getPrototypeOf(CodeBlock.prototype), 'format', this).call(this, name, value); - } - }, { - key: 'formatAt', - value: function formatAt(index, length, name, value) { - if (length === 0) return; - if (_parchment2.default.query(name, _parchment2.default.Scope.BLOCK) == null || name === this.statics.blotName && value === this.statics.formats(this.domNode)) { - return; - } - var nextNewline = this.newlineIndex(index); - if (nextNewline < 0 || nextNewline >= index + length) return; - var prevNewline = this.newlineIndex(index, true) + 1; - var isolateLength = nextNewline - prevNewline + 1; - var blot = this.isolate(prevNewline, isolateLength); - var next = blot.next; - blot.format(name, value); - if (next instanceof CodeBlock) { - next.formatAt(0, index - prevNewline + length - isolateLength, name, value); - } - } - }, { - key: 'insertAt', - value: function insertAt(index, value, def) { - if (def != null) return; - - var _descendant3 = this.descendant(_text2.default, index), - _descendant4 = _slicedToArray(_descendant3, 2), - text = _descendant4[0], - offset = _descendant4[1]; - - text.insertAt(offset, value); - } - }, { - key: 'length', - value: function length() { - var length = this.domNode.textContent.length; - if (!this.domNode.textContent.endsWith('\n')) { - return length + 1; - } - return length; - } - }, { - key: 'newlineIndex', - value: function newlineIndex(searchIndex) { - var reverse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - if (!reverse) { - var offset = this.domNode.textContent.slice(searchIndex).indexOf('\n'); - return offset > -1 ? searchIndex + offset : -1; - } else { - return this.domNode.textContent.slice(0, searchIndex).lastIndexOf('\n'); - } - } - }, { - key: 'optimize', - value: function optimize(context) { - if (!this.domNode.textContent.endsWith('\n')) { - this.appendChild(_parchment2.default.create('text', '\n')); - } - _get(CodeBlock.prototype.__proto__ || Object.getPrototypeOf(CodeBlock.prototype), 'optimize', this).call(this, context); - var next = this.next; - if (next != null && next.prev === this && next.statics.blotName === this.statics.blotName && this.statics.formats(this.domNode) === next.statics.formats(next.domNode)) { - next.optimize(context); - next.moveChildren(this); - next.remove(); - } - } - }, { - key: 'replace', - value: function replace(target) { - _get(CodeBlock.prototype.__proto__ || Object.getPrototypeOf(CodeBlock.prototype), 'replace', this).call(this, target); - [].slice.call(this.domNode.querySelectorAll('*')).forEach(function (node) { - var blot = _parchment2.default.find(node); - if (blot == null) { - node.parentNode.removeChild(node); - } else if (blot instanceof _parchment2.default.Embed) { - blot.remove(); - } else { - blot.unwrap(); - } - }); - } - }], [{ - key: 'create', - value: function create(value) { - var domNode = _get(CodeBlock.__proto__ || Object.getPrototypeOf(CodeBlock), 'create', this).call(this, value); - domNode.setAttribute('spellcheck', false); - return domNode; - } - }, { - key: 'formats', - value: function formats() { - return true; - } - }]); - - return CodeBlock; -}(_block2.default); - -CodeBlock.blotName = 'code-block'; -CodeBlock.tagName = 'PRE'; -CodeBlock.TAB = ' '; - -exports.Code = Code; -exports.default = CodeBlock; - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _quillDelta = __webpack_require__(2); - -var _quillDelta2 = _interopRequireDefault(_quillDelta); - -var _op = __webpack_require__(20); - -var _op2 = _interopRequireDefault(_op); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _code = __webpack_require__(13); - -var _code2 = _interopRequireDefault(_code); - -var _cursor = __webpack_require__(24); - -var _cursor2 = _interopRequireDefault(_cursor); - -var _block = __webpack_require__(4); - -var _block2 = _interopRequireDefault(_block); - -var _break = __webpack_require__(16); - -var _break2 = _interopRequireDefault(_break); - -var _clone = __webpack_require__(21); - -var _clone2 = _interopRequireDefault(_clone); - -var _deepEqual = __webpack_require__(11); - -var _deepEqual2 = _interopRequireDefault(_deepEqual); - -var _extend = __webpack_require__(3); - -var _extend2 = _interopRequireDefault(_extend); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var ASCII = /^[ -~]*$/; - -var Editor = function () { - function Editor(scroll) { - _classCallCheck(this, Editor); - - this.scroll = scroll; - this.delta = this.getDelta(); - } - - _createClass(Editor, [{ - key: 'applyDelta', - value: function applyDelta(delta) { - var _this = this; - - var consumeNextNewline = false; - this.scroll.update(); - var scrollLength = this.scroll.length(); - this.scroll.batchStart(); - delta = normalizeDelta(delta); - delta.reduce(function (index, op) { - var length = op.retain || op.delete || op.insert.length || 1; - var attributes = op.attributes || {}; - if (op.insert != null) { - if (typeof op.insert === 'string') { - var text = op.insert; - if (text.endsWith('\n') && consumeNextNewline) { - consumeNextNewline = false; - text = text.slice(0, -1); - } - if (index >= scrollLength && !text.endsWith('\n')) { - consumeNextNewline = true; - } - _this.scroll.insertAt(index, text); - - var _scroll$line = _this.scroll.line(index), - _scroll$line2 = _slicedToArray(_scroll$line, 2), - line = _scroll$line2[0], - offset = _scroll$line2[1]; - - var formats = (0, _extend2.default)({}, (0, _block.bubbleFormats)(line)); - if (line instanceof _block2.default) { - var _line$descendant = line.descendant(_parchment2.default.Leaf, offset), - _line$descendant2 = _slicedToArray(_line$descendant, 1), - leaf = _line$descendant2[0]; - - formats = (0, _extend2.default)(formats, (0, _block.bubbleFormats)(leaf)); - } - attributes = _op2.default.attributes.diff(formats, attributes) || {}; - } else if (_typeof(op.insert) === 'object') { - var key = Object.keys(op.insert)[0]; // There should only be one key - if (key == null) return index; - _this.scroll.insertAt(index, key, op.insert[key]); - } - scrollLength += length; - } - Object.keys(attributes).forEach(function (name) { - _this.scroll.formatAt(index, length, name, attributes[name]); - }); - return index + length; - }, 0); - delta.reduce(function (index, op) { - if (typeof op.delete === 'number') { - _this.scroll.deleteAt(index, op.delete); - return index; - } - return index + (op.retain || op.insert.length || 1); - }, 0); - this.scroll.batchEnd(); - return this.update(delta); - } - }, { - key: 'deleteText', - value: function deleteText(index, length) { - this.scroll.deleteAt(index, length); - return this.update(new _quillDelta2.default().retain(index).delete(length)); - } - }, { - key: 'formatLine', - value: function formatLine(index, length) { - var _this2 = this; - - var formats = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - this.scroll.update(); - Object.keys(formats).forEach(function (format) { - if (_this2.scroll.whitelist != null && !_this2.scroll.whitelist[format]) return; - var lines = _this2.scroll.lines(index, Math.max(length, 1)); - var lengthRemaining = length; - lines.forEach(function (line) { - var lineLength = line.length(); - if (!(line instanceof _code2.default)) { - line.format(format, formats[format]); - } else { - var codeIndex = index - line.offset(_this2.scroll); - var codeLength = line.newlineIndex(codeIndex + lengthRemaining) - codeIndex + 1; - line.formatAt(codeIndex, codeLength, format, formats[format]); - } - lengthRemaining -= lineLength; - }); - }); - this.scroll.optimize(); - return this.update(new _quillDelta2.default().retain(index).retain(length, (0, _clone2.default)(formats))); - } - }, { - key: 'formatText', - value: function formatText(index, length) { - var _this3 = this; - - var formats = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - Object.keys(formats).forEach(function (format) { - _this3.scroll.formatAt(index, length, format, formats[format]); - }); - return this.update(new _quillDelta2.default().retain(index).retain(length, (0, _clone2.default)(formats))); - } - }, { - key: 'getContents', - value: function getContents(index, length) { - return this.delta.slice(index, index + length); - } - }, { - key: 'getDelta', - value: function getDelta() { - return this.scroll.lines().reduce(function (delta, line) { - return delta.concat(line.delta()); - }, new _quillDelta2.default()); - } - }, { - key: 'getFormat', - value: function getFormat(index) { - var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - var lines = [], - leaves = []; - if (length === 0) { - this.scroll.path(index).forEach(function (path) { - var _path = _slicedToArray(path, 1), - blot = _path[0]; - - if (blot instanceof _block2.default) { - lines.push(blot); - } else if (blot instanceof _parchment2.default.Leaf) { - leaves.push(blot); - } - }); - } else { - lines = this.scroll.lines(index, length); - leaves = this.scroll.descendants(_parchment2.default.Leaf, index, length); - } - var formatsArr = [lines, leaves].map(function (blots) { - if (blots.length === 0) return {}; - var formats = (0, _block.bubbleFormats)(blots.shift()); - while (Object.keys(formats).length > 0) { - var blot = blots.shift(); - if (blot == null) return formats; - formats = combineFormats((0, _block.bubbleFormats)(blot), formats); - } - return formats; - }); - return _extend2.default.apply(_extend2.default, formatsArr); - } - }, { - key: 'getText', - value: function getText(index, length) { - return this.getContents(index, length).filter(function (op) { - return typeof op.insert === 'string'; - }).map(function (op) { - return op.insert; - }).join(''); - } - }, { - key: 'insertEmbed', - value: function insertEmbed(index, embed, value) { - this.scroll.insertAt(index, embed, value); - return this.update(new _quillDelta2.default().retain(index).insert(_defineProperty({}, embed, value))); - } - }, { - key: 'insertText', - value: function insertText(index, text) { - var _this4 = this; - - var formats = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - text = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); - this.scroll.insertAt(index, text); - Object.keys(formats).forEach(function (format) { - _this4.scroll.formatAt(index, text.length, format, formats[format]); - }); - return this.update(new _quillDelta2.default().retain(index).insert(text, (0, _clone2.default)(formats))); - } - }, { - key: 'isBlank', - value: function isBlank() { - if (this.scroll.children.length == 0) return true; - if (this.scroll.children.length > 1) return false; - var block = this.scroll.children.head; - if (block.statics.blotName !== _block2.default.blotName) return false; - if (block.children.length > 1) return false; - return block.children.head instanceof _break2.default; - } - }, { - key: 'removeFormat', - value: function removeFormat(index, length) { - var text = this.getText(index, length); - - var _scroll$line3 = this.scroll.line(index + length), - _scroll$line4 = _slicedToArray(_scroll$line3, 2), - line = _scroll$line4[0], - offset = _scroll$line4[1]; - - var suffixLength = 0, - suffix = new _quillDelta2.default(); - if (line != null) { - if (!(line instanceof _code2.default)) { - suffixLength = line.length() - offset; - } else { - suffixLength = line.newlineIndex(offset) - offset + 1; - } - suffix = line.delta().slice(offset, offset + suffixLength - 1).insert('\n'); - } - var contents = this.getContents(index, length + suffixLength); - var diff = contents.diff(new _quillDelta2.default().insert(text).concat(suffix)); - var delta = new _quillDelta2.default().retain(index).concat(diff); - return this.applyDelta(delta); - } - }, { - key: 'update', - value: function update(change) { - var mutations = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - var cursorIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; - - var oldDelta = this.delta; - if (mutations.length === 1 && mutations[0].type === 'characterData' && mutations[0].target.data.match(ASCII) && _parchment2.default.find(mutations[0].target)) { - // Optimization for character changes - var textBlot = _parchment2.default.find(mutations[0].target); - var formats = (0, _block.bubbleFormats)(textBlot); - var index = textBlot.offset(this.scroll); - var oldValue = mutations[0].oldValue.replace(_cursor2.default.CONTENTS, ''); - var oldText = new _quillDelta2.default().insert(oldValue); - var newText = new _quillDelta2.default().insert(textBlot.value()); - var diffDelta = new _quillDelta2.default().retain(index).concat(oldText.diff(newText, cursorIndex)); - change = diffDelta.reduce(function (delta, op) { - if (op.insert) { - return delta.insert(op.insert, formats); - } else { - return delta.push(op); - } - }, new _quillDelta2.default()); - this.delta = oldDelta.compose(change); - } else { - this.delta = this.getDelta(); - if (!change || !(0, _deepEqual2.default)(oldDelta.compose(change), this.delta)) { - change = oldDelta.diff(this.delta, cursorIndex); - } - } - return change; - } - }]); - - return Editor; -}(); - -function combineFormats(formats, combined) { - return Object.keys(combined).reduce(function (merged, name) { - if (formats[name] == null) return merged; - if (combined[name] === formats[name]) { - merged[name] = combined[name]; - } else if (Array.isArray(combined[name])) { - if (combined[name].indexOf(formats[name]) < 0) { - merged[name] = combined[name].concat([formats[name]]); - } - } else { - merged[name] = [combined[name], formats[name]]; - } - return merged; - }, {}); -} - -function normalizeDelta(delta) { - return delta.reduce(function (delta, op) { - if (op.insert === 1) { - var attributes = (0, _clone2.default)(op.attributes); - delete attributes['image']; - return delta.insert({ image: op.attributes.image }, attributes); - } - if (op.attributes != null && (op.attributes.list === true || op.attributes.bullet === true)) { - op = (0, _clone2.default)(op); - if (op.attributes.list) { - op.attributes.list = 'ordered'; - } else { - op.attributes.list = 'bullet'; - delete op.attributes.bullet; - } - } - if (typeof op.insert === 'string') { - var text = op.insert.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); - return delta.insert(text, op.attributes); - } - return delta.push(op); - }, new _quillDelta2.default()); -} - -exports.default = Editor; - -/***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.Range = undefined; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _clone = __webpack_require__(21); - -var _clone2 = _interopRequireDefault(_clone); - -var _deepEqual = __webpack_require__(11); - -var _deepEqual2 = _interopRequireDefault(_deepEqual); - -var _emitter3 = __webpack_require__(8); - -var _emitter4 = _interopRequireDefault(_emitter3); - -var _logger = __webpack_require__(10); - -var _logger2 = _interopRequireDefault(_logger); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var debug = (0, _logger2.default)('quill:selection'); - -var Range = function Range(index) { - var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - _classCallCheck(this, Range); - - this.index = index; - this.length = length; -}; - -var Selection = function () { - function Selection(scroll, emitter) { - var _this = this; - - _classCallCheck(this, Selection); - - this.emitter = emitter; - this.scroll = scroll; - this.composing = false; - this.mouseDown = false; - this.root = this.scroll.domNode; - this.cursor = _parchment2.default.create('cursor', this); - // savedRange is last non-null range - this.lastRange = this.savedRange = new Range(0, 0); - this.handleComposition(); - this.handleDragging(); - this.emitter.listenDOM('selectionchange', document, function () { - if (!_this.mouseDown) { - setTimeout(_this.update.bind(_this, _emitter4.default.sources.USER), 1); - } - }); - this.emitter.on(_emitter4.default.events.EDITOR_CHANGE, function (type, delta) { - if (type === _emitter4.default.events.TEXT_CHANGE && delta.length() > 0) { - _this.update(_emitter4.default.sources.SILENT); - } - }); - this.emitter.on(_emitter4.default.events.SCROLL_BEFORE_UPDATE, function () { - if (!_this.hasFocus()) return; - var native = _this.getNativeRange(); - if (native == null) return; - if (native.start.node === _this.cursor.textNode) return; // cursor.restore() will handle - // TODO unclear if this has negative side effects - _this.emitter.once(_emitter4.default.events.SCROLL_UPDATE, function () { - try { - _this.setNativeRange(native.start.node, native.start.offset, native.end.node, native.end.offset); - } catch (ignored) {} - }); - }); - this.emitter.on(_emitter4.default.events.SCROLL_OPTIMIZE, function (mutations, context) { - if (context.range) { - var _context$range = context.range, - startNode = _context$range.startNode, - startOffset = _context$range.startOffset, - endNode = _context$range.endNode, - endOffset = _context$range.endOffset; - - _this.setNativeRange(startNode, startOffset, endNode, endOffset); - } - }); - this.update(_emitter4.default.sources.SILENT); - } - - _createClass(Selection, [{ - key: 'handleComposition', - value: function handleComposition() { - var _this2 = this; - - this.root.addEventListener('compositionstart', function () { - _this2.composing = true; - }); - this.root.addEventListener('compositionend', function () { - _this2.composing = false; - if (_this2.cursor.parent) { - var range = _this2.cursor.restore(); - if (!range) return; - setTimeout(function () { - _this2.setNativeRange(range.startNode, range.startOffset, range.endNode, range.endOffset); - }, 1); - } - }); - } - }, { - key: 'handleDragging', - value: function handleDragging() { - var _this3 = this; - - this.emitter.listenDOM('mousedown', document.body, function () { - _this3.mouseDown = true; - }); - this.emitter.listenDOM('mouseup', document.body, function () { - _this3.mouseDown = false; - _this3.update(_emitter4.default.sources.USER); - }); - } - }, { - key: 'focus', - value: function focus() { - if (this.hasFocus()) return; - this.root.focus(); - this.setRange(this.savedRange); - } - }, { - key: 'format', - value: function format(_format, value) { - if (this.scroll.whitelist != null && !this.scroll.whitelist[_format]) return; - this.scroll.update(); - var nativeRange = this.getNativeRange(); - if (nativeRange == null || !nativeRange.native.collapsed || _parchment2.default.query(_format, _parchment2.default.Scope.BLOCK)) return; - if (nativeRange.start.node !== this.cursor.textNode) { - var blot = _parchment2.default.find(nativeRange.start.node, false); - if (blot == null) return; - // TODO Give blot ability to not split - if (blot instanceof _parchment2.default.Leaf) { - var after = blot.split(nativeRange.start.offset); - blot.parent.insertBefore(this.cursor, after); - } else { - blot.insertBefore(this.cursor, nativeRange.start.node); // Should never happen - } - this.cursor.attach(); - } - this.cursor.format(_format, value); - this.scroll.optimize(); - this.setNativeRange(this.cursor.textNode, this.cursor.textNode.data.length); - this.update(); - } - }, { - key: 'getBounds', - value: function getBounds(index) { - var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - var scrollLength = this.scroll.length(); - index = Math.min(index, scrollLength - 1); - length = Math.min(index + length, scrollLength - 1) - index; - var node = void 0, - _scroll$leaf = this.scroll.leaf(index), - _scroll$leaf2 = _slicedToArray(_scroll$leaf, 2), - leaf = _scroll$leaf2[0], - offset = _scroll$leaf2[1]; - if (leaf == null) return null; - - var _leaf$position = leaf.position(offset, true); - - var _leaf$position2 = _slicedToArray(_leaf$position, 2); - - node = _leaf$position2[0]; - offset = _leaf$position2[1]; - - var range = document.createRange(); - if (length > 0) { - range.setStart(node, offset); - - var _scroll$leaf3 = this.scroll.leaf(index + length); - - var _scroll$leaf4 = _slicedToArray(_scroll$leaf3, 2); - - leaf = _scroll$leaf4[0]; - offset = _scroll$leaf4[1]; - - if (leaf == null) return null; - - var _leaf$position3 = leaf.position(offset, true); - - var _leaf$position4 = _slicedToArray(_leaf$position3, 2); - - node = _leaf$position4[0]; - offset = _leaf$position4[1]; - - range.setEnd(node, offset); - return range.getBoundingClientRect(); - } else { - var side = 'left'; - var rect = void 0; - if (node instanceof Text) { - if (offset < node.data.length) { - range.setStart(node, offset); - range.setEnd(node, offset + 1); - } else { - range.setStart(node, offset - 1); - range.setEnd(node, offset); - side = 'right'; - } - rect = range.getBoundingClientRect(); - } else { - rect = leaf.domNode.getBoundingClientRect(); - if (offset > 0) side = 'right'; - } - return { - bottom: rect.top + rect.height, - height: rect.height, - left: rect[side], - right: rect[side], - top: rect.top, - width: 0 - }; - } - } - }, { - key: 'getNativeRange', - value: function getNativeRange() { - var selection = document.getSelection(); - if (selection == null || selection.rangeCount <= 0) return null; - var nativeRange = selection.getRangeAt(0); - if (nativeRange == null) return null; - var range = this.normalizeNative(nativeRange); - debug.info('getNativeRange', range); - return range; - } - }, { - key: 'getRange', - value: function getRange() { - var normalized = this.getNativeRange(); - if (normalized == null) return [null, null]; - var range = this.normalizedToRange(normalized); - return [range, normalized]; - } - }, { - key: 'hasFocus', - value: function hasFocus() { - return document.activeElement === this.root; - } - }, { - key: 'normalizedToRange', - value: function normalizedToRange(range) { - var _this4 = this; - - var positions = [[range.start.node, range.start.offset]]; - if (!range.native.collapsed) { - positions.push([range.end.node, range.end.offset]); - } - var indexes = positions.map(function (position) { - var _position = _slicedToArray(position, 2), - node = _position[0], - offset = _position[1]; - - var blot = _parchment2.default.find(node, true); - var index = blot.offset(_this4.scroll); - if (offset === 0) { - return index; - } else if (blot instanceof _parchment2.default.Container) { - return index + blot.length(); - } else { - return index + blot.index(node, offset); - } - }); - var end = Math.min(Math.max.apply(Math, _toConsumableArray(indexes)), this.scroll.length() - 1); - var start = Math.min.apply(Math, [end].concat(_toConsumableArray(indexes))); - return new Range(start, end - start); - } - }, { - key: 'normalizeNative', - value: function normalizeNative(nativeRange) { - if (!contains(this.root, nativeRange.startContainer) || !nativeRange.collapsed && !contains(this.root, nativeRange.endContainer)) { - return null; - } - var range = { - start: { node: nativeRange.startContainer, offset: nativeRange.startOffset }, - end: { node: nativeRange.endContainer, offset: nativeRange.endOffset }, - native: nativeRange - }; - [range.start, range.end].forEach(function (position) { - var node = position.node, - offset = position.offset; - while (!(node instanceof Text) && node.childNodes.length > 0) { - if (node.childNodes.length > offset) { - node = node.childNodes[offset]; - offset = 0; - } else if (node.childNodes.length === offset) { - node = node.lastChild; - offset = node instanceof Text ? node.data.length : node.childNodes.length + 1; - } else { - break; - } - } - position.node = node, position.offset = offset; - }); - return range; - } - }, { - key: 'rangeToNative', - value: function rangeToNative(range) { - var _this5 = this; - - var indexes = range.collapsed ? [range.index] : [range.index, range.index + range.length]; - var args = []; - var scrollLength = this.scroll.length(); - indexes.forEach(function (index, i) { - index = Math.min(scrollLength - 1, index); - var node = void 0, - _scroll$leaf5 = _this5.scroll.leaf(index), - _scroll$leaf6 = _slicedToArray(_scroll$leaf5, 2), - leaf = _scroll$leaf6[0], - offset = _scroll$leaf6[1]; - var _leaf$position5 = leaf.position(offset, i !== 0); - - var _leaf$position6 = _slicedToArray(_leaf$position5, 2); - - node = _leaf$position6[0]; - offset = _leaf$position6[1]; - - args.push(node, offset); - }); - if (args.length < 2) { - args = args.concat(args); - } - return args; - } - }, { - key: 'scrollIntoView', - value: function scrollIntoView(scrollingContainer) { - var range = this.lastRange; - if (range == null) return; - var bounds = this.getBounds(range.index, range.length); - if (bounds == null) return; - var limit = this.scroll.length() - 1; - - var _scroll$line = this.scroll.line(Math.min(range.index, limit)), - _scroll$line2 = _slicedToArray(_scroll$line, 1), - first = _scroll$line2[0]; - - var last = first; - if (range.length > 0) { - var _scroll$line3 = this.scroll.line(Math.min(range.index + range.length, limit)); - - var _scroll$line4 = _slicedToArray(_scroll$line3, 1); - - last = _scroll$line4[0]; - } - if (first == null || last == null || scrollingContainer == null) return; - var scrollBounds = scrollingContainer.getBoundingClientRect(); - if (bounds.top < scrollBounds.top) { - scrollingContainer.scrollTop -= scrollBounds.top - bounds.top; - } else if (bounds.bottom > scrollBounds.bottom) { - scrollingContainer.scrollTop += bounds.bottom - scrollBounds.bottom; - } - } - }, { - key: 'setNativeRange', - value: function setNativeRange(startNode, startOffset) { - var endNode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : startNode; - var endOffset = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : startOffset; - var force = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; - - debug.info('setNativeRange', startNode, startOffset, endNode, endOffset); - if (startNode != null && (this.root.parentNode == null || startNode.parentNode == null || endNode.parentNode == null)) { - return; - } - var selection = document.getSelection(); - if (selection == null) return; - if (startNode != null) { - if (!this.hasFocus()) this.root.focus(); - var native = (this.getNativeRange() || {}).native; - if (native == null || force || startNode !== native.startContainer || startOffset !== native.startOffset || endNode !== native.endContainer || endOffset !== native.endOffset) { - - if (startNode.tagName == "BR") { - startOffset = [].indexOf.call(startNode.parentNode.childNodes, startNode); - startNode = startNode.parentNode; - } - if (endNode.tagName == "BR") { - endOffset = [].indexOf.call(endNode.parentNode.childNodes, endNode); - endNode = endNode.parentNode; - } - var range = document.createRange(); - range.setStart(startNode, startOffset); - range.setEnd(endNode, endOffset); - selection.removeAllRanges(); - selection.addRange(range); - } - } else { - selection.removeAllRanges(); - this.root.blur(); - document.body.focus(); // root.blur() not enough on IE11+Travis+SauceLabs (but not local VMs) - } - } - }, { - key: 'setRange', - value: function setRange(range) { - var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - var source = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _emitter4.default.sources.API; - - if (typeof force === 'string') { - source = force; - force = false; - } - debug.info('setRange', range); - if (range != null) { - var args = this.rangeToNative(range); - this.setNativeRange.apply(this, _toConsumableArray(args).concat([force])); - } else { - this.setNativeRange(null); - } - this.update(source); - } - }, { - key: 'update', - value: function update() { - var source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _emitter4.default.sources.USER; - - var oldRange = this.lastRange; - - var _getRange = this.getRange(), - _getRange2 = _slicedToArray(_getRange, 2), - lastRange = _getRange2[0], - nativeRange = _getRange2[1]; - - this.lastRange = lastRange; - if (this.lastRange != null) { - this.savedRange = this.lastRange; - } - if (!(0, _deepEqual2.default)(oldRange, this.lastRange)) { - var _emitter; - - if (!this.composing && nativeRange != null && nativeRange.native.collapsed && nativeRange.start.node !== this.cursor.textNode) { - this.cursor.restore(); - } - var args = [_emitter4.default.events.SELECTION_CHANGE, (0, _clone2.default)(this.lastRange), (0, _clone2.default)(oldRange), source]; - (_emitter = this.emitter).emit.apply(_emitter, [_emitter4.default.events.EDITOR_CHANGE].concat(args)); - if (source !== _emitter4.default.sources.SILENT) { - var _emitter2; - - (_emitter2 = this.emitter).emit.apply(_emitter2, args); - } - } - } - }]); - - return Selection; -}(); - -function contains(parent, descendant) { - try { - // Firefox inserts inaccessible nodes around video elements - descendant.parentNode; - } catch (e) { - return false; - } - // IE11 has bug with Text nodes - // https://connect.microsoft.com/IE/feedback/details/780874/node-contains-is-incorrect - if (descendant instanceof Text) { - descendant = descendant.parentNode; - } - return parent.contains(descendant); -} - -exports.Range = Range; -exports.default = Selection; - -/***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Break = function (_Parchment$Embed) { - _inherits(Break, _Parchment$Embed); - - function Break() { - _classCallCheck(this, Break); - - return _possibleConstructorReturn(this, (Break.__proto__ || Object.getPrototypeOf(Break)).apply(this, arguments)); - } - - _createClass(Break, [{ - key: 'insertInto', - value: function insertInto(parent, ref) { - if (parent.children.length === 0) { - _get(Break.prototype.__proto__ || Object.getPrototypeOf(Break.prototype), 'insertInto', this).call(this, parent, ref); - } else { - this.remove(); - } - } - }, { - key: 'length', - value: function length() { - return 0; - } - }, { - key: 'value', - value: function value() { - return ''; - } - }], [{ - key: 'value', - value: function value() { - return undefined; - } - }]); - - return Break; -}(_parchment2.default.Embed); - -Break.blotName = 'break'; -Break.tagName = 'BR'; - -exports.default = Break; - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var linked_list_1 = __webpack_require__(44); -var shadow_1 = __webpack_require__(30); -var Registry = __webpack_require__(1); -var ContainerBlot = /** @class */ (function (_super) { - __extends(ContainerBlot, _super); - function ContainerBlot(domNode) { - var _this = _super.call(this, domNode) || this; - _this.build(); - return _this; - } - ContainerBlot.prototype.appendChild = function (other) { - this.insertBefore(other); - }; - ContainerBlot.prototype.attach = function () { - _super.prototype.attach.call(this); - this.children.forEach(function (child) { - child.attach(); - }); - }; - ContainerBlot.prototype.build = function () { - var _this = this; - this.children = new linked_list_1.default(); - // Need to be reversed for if DOM nodes already in order - [].slice - .call(this.domNode.childNodes) - .reverse() - .forEach(function (node) { - try { - var child = makeBlot(node); - _this.insertBefore(child, _this.children.head || undefined); - } - catch (err) { - if (err instanceof Registry.ParchmentError) - return; - else - throw err; - } - }); - }; - ContainerBlot.prototype.deleteAt = function (index, length) { - if (index === 0 && length === this.length()) { - return this.remove(); - } - this.children.forEachAt(index, length, function (child, offset, length) { - child.deleteAt(offset, length); - }); - }; - ContainerBlot.prototype.descendant = function (criteria, index) { - var _a = this.children.find(index), child = _a[0], offset = _a[1]; - if ((criteria.blotName == null && criteria(child)) || - (criteria.blotName != null && child instanceof criteria)) { - return [child, offset]; - } - else if (child instanceof ContainerBlot) { - return child.descendant(criteria, offset); - } - else { - return [null, -1]; - } - }; - ContainerBlot.prototype.descendants = function (criteria, index, length) { - if (index === void 0) { index = 0; } - if (length === void 0) { length = Number.MAX_VALUE; } - var descendants = []; - var lengthLeft = length; - this.children.forEachAt(index, length, function (child, index, length) { - if ((criteria.blotName == null && criteria(child)) || - (criteria.blotName != null && child instanceof criteria)) { - descendants.push(child); - } - if (child instanceof ContainerBlot) { - descendants = descendants.concat(child.descendants(criteria, index, lengthLeft)); - } - lengthLeft -= length; - }); - return descendants; - }; - ContainerBlot.prototype.detach = function () { - this.children.forEach(function (child) { - child.detach(); - }); - _super.prototype.detach.call(this); - }; - ContainerBlot.prototype.formatAt = function (index, length, name, value) { - this.children.forEachAt(index, length, function (child, offset, length) { - child.formatAt(offset, length, name, value); - }); - }; - ContainerBlot.prototype.insertAt = function (index, value, def) { - var _a = this.children.find(index), child = _a[0], offset = _a[1]; - if (child) { - child.insertAt(offset, value, def); - } - else { - var blot = def == null ? Registry.create('text', value) : Registry.create(value, def); - this.appendChild(blot); - } - }; - ContainerBlot.prototype.insertBefore = function (childBlot, refBlot) { - if (this.statics.allowedChildren != null && - !this.statics.allowedChildren.some(function (child) { - return childBlot instanceof child; - })) { - throw new Registry.ParchmentError("Cannot insert " + childBlot.statics.blotName + " into " + this.statics.blotName); - } - childBlot.insertInto(this, refBlot); - }; - ContainerBlot.prototype.length = function () { - return this.children.reduce(function (memo, child) { - return memo + child.length(); - }, 0); - }; - ContainerBlot.prototype.moveChildren = function (targetParent, refNode) { - this.children.forEach(function (child) { - targetParent.insertBefore(child, refNode); - }); - }; - ContainerBlot.prototype.optimize = function (context) { - _super.prototype.optimize.call(this, context); - if (this.children.length === 0) { - if (this.statics.defaultChild != null) { - var child = Registry.create(this.statics.defaultChild); - this.appendChild(child); - child.optimize(context); - } - else { - this.remove(); - } - } - }; - ContainerBlot.prototype.path = function (index, inclusive) { - if (inclusive === void 0) { inclusive = false; } - var _a = this.children.find(index, inclusive), child = _a[0], offset = _a[1]; - var position = [[this, index]]; - if (child instanceof ContainerBlot) { - return position.concat(child.path(offset, inclusive)); - } - else if (child != null) { - position.push([child, offset]); - } - return position; - }; - ContainerBlot.prototype.removeChild = function (child) { - this.children.remove(child); - }; - ContainerBlot.prototype.replace = function (target) { - if (target instanceof ContainerBlot) { - target.moveChildren(this); - } - _super.prototype.replace.call(this, target); - }; - ContainerBlot.prototype.split = function (index, force) { - if (force === void 0) { force = false; } - if (!force) { - if (index === 0) - return this; - if (index === this.length()) - return this.next; - } - var after = this.clone(); - this.parent.insertBefore(after, this.next); - this.children.forEachAt(index, this.length(), function (child, offset, length) { - child = child.split(offset, force); - after.appendChild(child); - }); - return after; - }; - ContainerBlot.prototype.unwrap = function () { - this.moveChildren(this.parent, this.next); - this.remove(); - }; - ContainerBlot.prototype.update = function (mutations, context) { - var _this = this; - var addedNodes = []; - var removedNodes = []; - mutations.forEach(function (mutation) { - if (mutation.target === _this.domNode && mutation.type === 'childList') { - addedNodes.push.apply(addedNodes, mutation.addedNodes); - removedNodes.push.apply(removedNodes, mutation.removedNodes); - } - }); - removedNodes.forEach(function (node) { - // Check node has actually been removed - // One exception is Chrome does not immediately remove IFRAMEs - // from DOM but MutationRecord is correct in its reported removal - if (node.parentNode != null && - // @ts-ignore - node.tagName !== 'IFRAME' && - document.body.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_CONTAINED_BY) { - return; - } - var blot = Registry.find(node); - if (blot == null) - return; - if (blot.domNode.parentNode == null || blot.domNode.parentNode === _this.domNode) { - blot.detach(); - } - }); - addedNodes - .filter(function (node) { - return node.parentNode == _this.domNode; - }) - .sort(function (a, b) { - if (a === b) - return 0; - if (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING) { - return 1; - } - return -1; - }) - .forEach(function (node) { - var refBlot = null; - if (node.nextSibling != null) { - refBlot = Registry.find(node.nextSibling); - } - var blot = makeBlot(node); - if (blot.next != refBlot || blot.next == null) { - if (blot.parent != null) { - blot.parent.removeChild(_this); - } - _this.insertBefore(blot, refBlot || undefined); - } - }); - }; - return ContainerBlot; -}(shadow_1.default)); -function makeBlot(node) { - var blot = Registry.find(node); - if (blot == null) { - try { - blot = Registry.create(node); - } - catch (e) { - blot = Registry.create(Registry.Scope.INLINE); - [].slice.call(node.childNodes).forEach(function (child) { - // @ts-ignore - blot.domNode.appendChild(child); - }); - if (node.parentNode) { - node.parentNode.replaceChild(blot.domNode, node); - } - blot.attach(); - } - } - return blot; -} -exports.default = ContainerBlot; - - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var attributor_1 = __webpack_require__(12); -var store_1 = __webpack_require__(31); -var container_1 = __webpack_require__(17); -var Registry = __webpack_require__(1); -var FormatBlot = /** @class */ (function (_super) { - __extends(FormatBlot, _super); - function FormatBlot(domNode) { - var _this = _super.call(this, domNode) || this; - _this.attributes = new store_1.default(_this.domNode); - return _this; - } - FormatBlot.formats = function (domNode) { - if (typeof this.tagName === 'string') { - return true; - } - else if (Array.isArray(this.tagName)) { - return domNode.tagName.toLowerCase(); - } - return undefined; - }; - FormatBlot.prototype.format = function (name, value) { - var format = Registry.query(name); - if (format instanceof attributor_1.default) { - this.attributes.attribute(format, value); - } - else if (value) { - if (format != null && (name !== this.statics.blotName || this.formats()[name] !== value)) { - this.replaceWith(name, value); - } - } - }; - FormatBlot.prototype.formats = function () { - var formats = this.attributes.values(); - var format = this.statics.formats(this.domNode); - if (format != null) { - formats[this.statics.blotName] = format; - } - return formats; - }; - FormatBlot.prototype.replaceWith = function (name, value) { - var replacement = _super.prototype.replaceWith.call(this, name, value); - this.attributes.copy(replacement); - return replacement; - }; - FormatBlot.prototype.update = function (mutations, context) { - var _this = this; - _super.prototype.update.call(this, mutations, context); - if (mutations.some(function (mutation) { - return mutation.target === _this.domNode && mutation.type === 'attributes'; - })) { - this.attributes.build(); - } - }; - FormatBlot.prototype.wrap = function (name, value) { - var wrapper = _super.prototype.wrap.call(this, name, value); - if (wrapper instanceof FormatBlot && wrapper.statics.scope === this.statics.scope) { - this.attributes.move(wrapper); - } - return wrapper; - }; - return FormatBlot; -}(container_1.default)); -exports.default = FormatBlot; - - -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var shadow_1 = __webpack_require__(30); -var Registry = __webpack_require__(1); -var LeafBlot = /** @class */ (function (_super) { - __extends(LeafBlot, _super); - function LeafBlot() { - return _super !== null && _super.apply(this, arguments) || this; - } - LeafBlot.value = function (domNode) { - return true; - }; - LeafBlot.prototype.index = function (node, offset) { - if (this.domNode === node || - this.domNode.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_CONTAINED_BY) { - return Math.min(offset, 1); - } - return -1; - }; - LeafBlot.prototype.position = function (index, inclusive) { - var offset = [].indexOf.call(this.parent.domNode.childNodes, this.domNode); - if (index > 0) - offset += 1; - return [this.parent.domNode, offset]; - }; - LeafBlot.prototype.value = function () { - var _a; - return _a = {}, _a[this.statics.blotName] = this.statics.value(this.domNode) || true, _a; - }; - LeafBlot.scope = Registry.Scope.INLINE_BLOT; - return LeafBlot; -}(shadow_1.default)); -exports.default = LeafBlot; - - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -var equal = __webpack_require__(11); -var extend = __webpack_require__(3); - - -var lib = { - attributes: { - compose: function (a, b, keepNull) { - if (typeof a !== 'object') a = {}; - if (typeof b !== 'object') b = {}; - var attributes = extend(true, {}, b); - if (!keepNull) { - attributes = Object.keys(attributes).reduce(function (copy, key) { - if (attributes[key] != null) { - copy[key] = attributes[key]; - } - return copy; - }, {}); - } - for (var key in a) { - if (a[key] !== undefined && b[key] === undefined) { - attributes[key] = a[key]; - } - } - return Object.keys(attributes).length > 0 ? attributes : undefined; - }, - - diff: function(a, b) { - if (typeof a !== 'object') a = {}; - if (typeof b !== 'object') b = {}; - var attributes = Object.keys(a).concat(Object.keys(b)).reduce(function (attributes, key) { - if (!equal(a[key], b[key])) { - attributes[key] = b[key] === undefined ? null : b[key]; - } - return attributes; - }, {}); - return Object.keys(attributes).length > 0 ? attributes : undefined; - }, - - transform: function (a, b, priority) { - if (typeof a !== 'object') return b; - if (typeof b !== 'object') return undefined; - if (!priority) return b; // b simply overwrites us without priority - var attributes = Object.keys(b).reduce(function (attributes, key) { - if (a[key] === undefined) attributes[key] = b[key]; // null is a valid value - return attributes; - }, {}); - return Object.keys(attributes).length > 0 ? attributes : undefined; - } - }, - - iterator: function (ops) { - return new Iterator(ops); - }, - - length: function (op) { - if (typeof op['delete'] === 'number') { - return op['delete']; - } else if (typeof op.retain === 'number') { - return op.retain; - } else { - return typeof op.insert === 'string' ? op.insert.length : 1; - } - } -}; - - -function Iterator(ops) { - this.ops = ops; - this.index = 0; - this.offset = 0; -}; - -Iterator.prototype.hasNext = function () { - return this.peekLength() < Infinity; -}; - -Iterator.prototype.next = function (length) { - if (!length) length = Infinity; - var nextOp = this.ops[this.index]; - if (nextOp) { - var offset = this.offset; - var opLength = lib.length(nextOp) - if (length >= opLength - offset) { - length = opLength - offset; - this.index += 1; - this.offset = 0; - } else { - this.offset += length; - } - if (typeof nextOp['delete'] === 'number') { - return { 'delete': length }; - } else { - var retOp = {}; - if (nextOp.attributes) { - retOp.attributes = nextOp.attributes; - } - if (typeof nextOp.retain === 'number') { - retOp.retain = length; - } else if (typeof nextOp.insert === 'string') { - retOp.insert = nextOp.insert.substr(offset, length); - } else { - // offset should === 0, length should === 1 - retOp.insert = nextOp.insert; - } - return retOp; - } - } else { - return { retain: Infinity }; - } -}; - -Iterator.prototype.peek = function () { - return this.ops[this.index]; -}; - -Iterator.prototype.peekLength = function () { - if (this.ops[this.index]) { - // Should never return 0 if our index is being managed correctly - return lib.length(this.ops[this.index]) - this.offset; - } else { - return Infinity; - } -}; - -Iterator.prototype.peekType = function () { - if (this.ops[this.index]) { - if (typeof this.ops[this.index]['delete'] === 'number') { - return 'delete'; - } else if (typeof this.ops[this.index].retain === 'number') { - return 'retain'; - } else { - return 'insert'; - } - } - return 'retain'; -}; - -Iterator.prototype.rest = function () { - if (!this.hasNext()) { - return []; - } else if (this.offset === 0) { - return this.ops.slice(this.index); - } else { - var offset = this.offset; - var index = this.index; - var next = this.next(); - var rest = this.ops.slice(this.index); - this.offset = offset; - this.index = index; - return [next].concat(rest); - } -}; - - -module.exports = lib; - - -/***/ }), -/* 21 */ -/***/ (function(module, exports) { - -var clone = (function() { -'use strict'; - -function _instanceof(obj, type) { - return type != null && obj instanceof type; -} - -var nativeMap; -try { - nativeMap = Map; -} catch(_) { - // maybe a reference error because no `Map`. Give it a dummy value that no - // value will ever be an instanceof. - nativeMap = function() {}; -} - -var nativeSet; -try { - nativeSet = Set; -} catch(_) { - nativeSet = function() {}; -} - -var nativePromise; -try { - nativePromise = Promise; -} catch(_) { - nativePromise = function() {}; -} - -/** - * Clones (copies) an Object using deep copying. - * - * This function supports circular references by default, but if you are certain - * there are no circular references in your object, you can save some CPU time - * by calling clone(obj, false). - * - * Caution: if `circular` is false and `parent` contains circular references, - * your program may enter an infinite loop and crash. - * - * @param `parent` - the object to be cloned - * @param `circular` - set to true if the object to be cloned may contain - * circular references. (optional - true by default) - * @param `depth` - set to a number if the object is only to be cloned to - * a particular depth. (optional - defaults to Infinity) - * @param `prototype` - sets the prototype to be used when cloning an object. - * (optional - defaults to parent prototype). - * @param `includeNonEnumerable` - set to true if the non-enumerable properties - * should be cloned as well. Non-enumerable properties on the prototype - * chain will be ignored. (optional - false by default) -*/ -function clone(parent, circular, depth, prototype, includeNonEnumerable) { - if (typeof circular === 'object') { - depth = circular.depth; - prototype = circular.prototype; - includeNonEnumerable = circular.includeNonEnumerable; - circular = circular.circular; - } - // maintain two arrays for circular references, where corresponding parents - // and children have the same index - var allParents = []; - var allChildren = []; - - var useBuffer = typeof Buffer != 'undefined'; - - if (typeof circular == 'undefined') - circular = true; - - if (typeof depth == 'undefined') - depth = Infinity; - - // recurse this function so we don't reset allParents and allChildren - function _clone(parent, depth) { - // cloning null always returns null - if (parent === null) - return null; - - if (depth === 0) - return parent; - - var child; - var proto; - if (typeof parent != 'object') { - return parent; - } - - if (_instanceof(parent, nativeMap)) { - child = new nativeMap(); - } else if (_instanceof(parent, nativeSet)) { - child = new nativeSet(); - } else if (_instanceof(parent, nativePromise)) { - child = new nativePromise(function (resolve, reject) { - parent.then(function(value) { - resolve(_clone(value, depth - 1)); - }, function(err) { - reject(_clone(err, depth - 1)); - }); - }); - } else if (clone.__isArray(parent)) { - child = []; - } else if (clone.__isRegExp(parent)) { - child = new RegExp(parent.source, __getRegExpFlags(parent)); - if (parent.lastIndex) child.lastIndex = parent.lastIndex; - } else if (clone.__isDate(parent)) { - child = new Date(parent.getTime()); - } else if (useBuffer && Buffer.isBuffer(parent)) { - if (Buffer.allocUnsafe) { - // Node.js >= 4.5.0 - child = Buffer.allocUnsafe(parent.length); - } else { - // Older Node.js versions - child = new Buffer(parent.length); - } - parent.copy(child); - return child; - } else if (_instanceof(parent, Error)) { - child = Object.create(parent); - } else { - if (typeof prototype == 'undefined') { - proto = Object.getPrototypeOf(parent); - child = Object.create(proto); - } - else { - child = Object.create(prototype); - proto = prototype; - } - } - - if (circular) { - var index = allParents.indexOf(parent); - - if (index != -1) { - return allChildren[index]; - } - allParents.push(parent); - allChildren.push(child); - } - - if (_instanceof(parent, nativeMap)) { - parent.forEach(function(value, key) { - var keyChild = _clone(key, depth - 1); - var valueChild = _clone(value, depth - 1); - child.set(keyChild, valueChild); - }); - } - if (_instanceof(parent, nativeSet)) { - parent.forEach(function(value) { - var entryChild = _clone(value, depth - 1); - child.add(entryChild); - }); - } - - for (var i in parent) { - var attrs; - if (proto) { - attrs = Object.getOwnPropertyDescriptor(proto, i); - } - - if (attrs && attrs.set == null) { - continue; - } - child[i] = _clone(parent[i], depth - 1); - } - - if (Object.getOwnPropertySymbols) { - var symbols = Object.getOwnPropertySymbols(parent); - for (var i = 0; i < symbols.length; i++) { - // Don't need to worry about cloning a symbol because it is a primitive, - // like a number or string. - var symbol = symbols[i]; - var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); - if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { - continue; - } - child[symbol] = _clone(parent[symbol], depth - 1); - if (!descriptor.enumerable) { - Object.defineProperty(child, symbol, { - enumerable: false - }); - } - } - } - - if (includeNonEnumerable) { - var allPropertyNames = Object.getOwnPropertyNames(parent); - for (var i = 0; i < allPropertyNames.length; i++) { - var propertyName = allPropertyNames[i]; - var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); - if (descriptor && descriptor.enumerable) { - continue; - } - child[propertyName] = _clone(parent[propertyName], depth - 1); - Object.defineProperty(child, propertyName, { - enumerable: false - }); - } - } - - return child; - } - - return _clone(parent, depth); -} - -/** - * Simple flat clone using prototype, accepts only objects, usefull for property - * override on FLAT configuration object (no nested props). - * - * USE WITH CAUTION! This may not behave as you wish if you do not know how this - * works. - */ -clone.clonePrototype = function clonePrototype(parent) { - if (parent === null) - return null; - - var c = function () {}; - c.prototype = parent; - return new c(); -}; - -// private utility functions - -function __objToStr(o) { - return Object.prototype.toString.call(o); -} -clone.__objToStr = __objToStr; - -function __isDate(o) { - return typeof o === 'object' && __objToStr(o) === '[object Date]'; -} -clone.__isDate = __isDate; - -function __isArray(o) { - return typeof o === 'object' && __objToStr(o) === '[object Array]'; -} -clone.__isArray = __isArray; - -function __isRegExp(o) { - return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; -} -clone.__isRegExp = __isRegExp; - -function __getRegExpFlags(re) { - var flags = ''; - if (re.global) flags += 'g'; - if (re.ignoreCase) flags += 'i'; - if (re.multiline) flags += 'm'; - return flags; -} -clone.__getRegExpFlags = __getRegExpFlags; - -return clone; -})(); - -if (typeof module === 'object' && module.exports) { - module.exports = clone; -} - - -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _emitter = __webpack_require__(8); - -var _emitter2 = _interopRequireDefault(_emitter); - -var _block = __webpack_require__(4); - -var _block2 = _interopRequireDefault(_block); - -var _break = __webpack_require__(16); - -var _break2 = _interopRequireDefault(_break); - -var _code = __webpack_require__(13); - -var _code2 = _interopRequireDefault(_code); - -var _container = __webpack_require__(25); - -var _container2 = _interopRequireDefault(_container); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -function isLine(blot) { - return blot instanceof _block2.default || blot instanceof _block.BlockEmbed; -} - -var Scroll = function (_Parchment$Scroll) { - _inherits(Scroll, _Parchment$Scroll); - - function Scroll(domNode, config) { - _classCallCheck(this, Scroll); - - var _this = _possibleConstructorReturn(this, (Scroll.__proto__ || Object.getPrototypeOf(Scroll)).call(this, domNode)); - - _this.emitter = config.emitter; - if (Array.isArray(config.whitelist)) { - _this.whitelist = config.whitelist.reduce(function (whitelist, format) { - whitelist[format] = true; - return whitelist; - }, {}); - } - // Some reason fixes composition issues with character languages in Windows/Chrome, Safari - _this.domNode.addEventListener('DOMNodeInserted', function () {}); - _this.optimize(); - _this.enable(); - return _this; - } - - _createClass(Scroll, [{ - key: 'batchStart', - value: function batchStart() { - this.batch = true; - } - }, { - key: 'batchEnd', - value: function batchEnd() { - this.batch = false; - this.optimize(); - } - }, { - key: 'deleteAt', - value: function deleteAt(index, length) { - var _line = this.line(index), - _line2 = _slicedToArray(_line, 2), - first = _line2[0], - offset = _line2[1]; - - var _line3 = this.line(index + length), - _line4 = _slicedToArray(_line3, 1), - last = _line4[0]; - - _get(Scroll.prototype.__proto__ || Object.getPrototypeOf(Scroll.prototype), 'deleteAt', this).call(this, index, length); - if (last != null && first !== last && offset > 0) { - if (first instanceof _block.BlockEmbed || last instanceof _block.BlockEmbed) { - this.optimize(); - return; - } - if (first instanceof _code2.default) { - var newlineIndex = first.newlineIndex(first.length(), true); - if (newlineIndex > -1) { - first = first.split(newlineIndex + 1); - if (first === last) { - this.optimize(); - return; - } - } - } else if (last instanceof _code2.default) { - var _newlineIndex = last.newlineIndex(0); - if (_newlineIndex > -1) { - last.split(_newlineIndex + 1); - } - } - var ref = last.children.head instanceof _break2.default ? null : last.children.head; - first.moveChildren(last, ref); - first.remove(); - } - this.optimize(); - } - }, { - key: 'enable', - value: function enable() { - var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - - this.domNode.setAttribute('contenteditable', enabled); - } - }, { - key: 'formatAt', - value: function formatAt(index, length, format, value) { - if (this.whitelist != null && !this.whitelist[format]) return; - _get(Scroll.prototype.__proto__ || Object.getPrototypeOf(Scroll.prototype), 'formatAt', this).call(this, index, length, format, value); - this.optimize(); - } - }, { - key: 'insertAt', - value: function insertAt(index, value, def) { - if (def != null && this.whitelist != null && !this.whitelist[value]) return; - if (index >= this.length()) { - if (def == null || _parchment2.default.query(value, _parchment2.default.Scope.BLOCK) == null) { - var blot = _parchment2.default.create(this.statics.defaultChild); - this.appendChild(blot); - if (def == null && value.endsWith('\n')) { - value = value.slice(0, -1); - } - blot.insertAt(0, value, def); - } else { - var embed = _parchment2.default.create(value, def); - this.appendChild(embed); - } - } else { - _get(Scroll.prototype.__proto__ || Object.getPrototypeOf(Scroll.prototype), 'insertAt', this).call(this, index, value, def); - } - this.optimize(); - } - }, { - key: 'insertBefore', - value: function insertBefore(blot, ref) { - if (blot.statics.scope === _parchment2.default.Scope.INLINE_BLOT) { - var wrapper = _parchment2.default.create(this.statics.defaultChild); - wrapper.appendChild(blot); - blot = wrapper; - } - _get(Scroll.prototype.__proto__ || Object.getPrototypeOf(Scroll.prototype), 'insertBefore', this).call(this, blot, ref); - } - }, { - key: 'leaf', - value: function leaf(index) { - return this.path(index).pop() || [null, -1]; - } - }, { - key: 'line', - value: function line(index) { - if (index === this.length()) { - return this.line(index - 1); - } - return this.descendant(isLine, index); - } - }, { - key: 'lines', - value: function lines() { - var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Number.MAX_VALUE; - - var getLines = function getLines(blot, index, length) { - var lines = [], - lengthLeft = length; - blot.children.forEachAt(index, length, function (child, index, length) { - if (isLine(child)) { - lines.push(child); - } else if (child instanceof _parchment2.default.Container) { - lines = lines.concat(getLines(child, index, lengthLeft)); - } - lengthLeft -= length; - }); - return lines; - }; - return getLines(this, index, length); - } - }, { - key: 'optimize', - value: function optimize() { - var mutations = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; - var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (this.batch === true) return; - _get(Scroll.prototype.__proto__ || Object.getPrototypeOf(Scroll.prototype), 'optimize', this).call(this, mutations, context); - if (mutations.length > 0) { - this.emitter.emit(_emitter2.default.events.SCROLL_OPTIMIZE, mutations, context); - } - } - }, { - key: 'path', - value: function path(index) { - return _get(Scroll.prototype.__proto__ || Object.getPrototypeOf(Scroll.prototype), 'path', this).call(this, index).slice(1); // Exclude self - } - }, { - key: 'update', - value: function update(mutations) { - if (this.batch === true) return; - var source = _emitter2.default.sources.USER; - if (typeof mutations === 'string') { - source = mutations; - } - if (!Array.isArray(mutations)) { - mutations = this.observer.takeRecords(); - } - if (mutations.length > 0) { - this.emitter.emit(_emitter2.default.events.SCROLL_BEFORE_UPDATE, source, mutations); - } - _get(Scroll.prototype.__proto__ || Object.getPrototypeOf(Scroll.prototype), 'update', this).call(this, mutations.concat([])); // pass copy - if (mutations.length > 0) { - this.emitter.emit(_emitter2.default.events.SCROLL_UPDATE, source, mutations); - } - } - }]); - - return Scroll; -}(_parchment2.default.Scroll); - -Scroll.blotName = 'scroll'; -Scroll.className = 'ql-editor'; -Scroll.tagName = 'DIV'; -Scroll.defaultChild = 'block'; -Scroll.allowedChildren = [_block2.default, _block.BlockEmbed, _container2.default]; - -exports.default = Scroll; - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.SHORTKEY = exports.default = undefined; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _clone = __webpack_require__(21); - -var _clone2 = _interopRequireDefault(_clone); - -var _deepEqual = __webpack_require__(11); - -var _deepEqual2 = _interopRequireDefault(_deepEqual); - -var _extend = __webpack_require__(3); - -var _extend2 = _interopRequireDefault(_extend); - -var _quillDelta = __webpack_require__(2); - -var _quillDelta2 = _interopRequireDefault(_quillDelta); - -var _op = __webpack_require__(20); - -var _op2 = _interopRequireDefault(_op); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _quill = __webpack_require__(5); - -var _quill2 = _interopRequireDefault(_quill); - -var _logger = __webpack_require__(10); - -var _logger2 = _interopRequireDefault(_logger); - -var _module = __webpack_require__(9); - -var _module2 = _interopRequireDefault(_module); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var debug = (0, _logger2.default)('quill:keyboard'); - -var SHORTKEY = /Mac/i.test(navigator.platform) ? 'metaKey' : 'ctrlKey'; - -var Keyboard = function (_Module) { - _inherits(Keyboard, _Module); - - _createClass(Keyboard, null, [{ - key: 'match', - value: function match(evt, binding) { - binding = normalize(binding); - if (['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].some(function (key) { - return !!binding[key] !== evt[key] && binding[key] !== null; - })) { - return false; - } - return binding.key === (evt.which || evt.keyCode); - } - }]); - - function Keyboard(quill, options) { - _classCallCheck(this, Keyboard); - - var _this = _possibleConstructorReturn(this, (Keyboard.__proto__ || Object.getPrototypeOf(Keyboard)).call(this, quill, options)); - - _this.bindings = {}; - Object.keys(_this.options.bindings).forEach(function (name) { - if (name === 'list autofill' && quill.scroll.whitelist != null && !quill.scroll.whitelist['list']) { - return; - } - if (_this.options.bindings[name]) { - _this.addBinding(_this.options.bindings[name]); - } - }); - _this.addBinding({ key: Keyboard.keys.ENTER, shiftKey: null }, handleEnter); - _this.addBinding({ key: Keyboard.keys.ENTER, metaKey: null, ctrlKey: null, altKey: null }, function () {}); - if (/Firefox/i.test(navigator.userAgent)) { - // Need to handle delete and backspace for Firefox in the general case #1171 - _this.addBinding({ key: Keyboard.keys.BACKSPACE }, { collapsed: true }, handleBackspace); - _this.addBinding({ key: Keyboard.keys.DELETE }, { collapsed: true }, handleDelete); - } else { - _this.addBinding({ key: Keyboard.keys.BACKSPACE }, { collapsed: true, prefix: /^.?$/ }, handleBackspace); - _this.addBinding({ key: Keyboard.keys.DELETE }, { collapsed: true, suffix: /^.?$/ }, handleDelete); - } - _this.addBinding({ key: Keyboard.keys.BACKSPACE }, { collapsed: false }, handleDeleteRange); - _this.addBinding({ key: Keyboard.keys.DELETE }, { collapsed: false }, handleDeleteRange); - _this.addBinding({ key: Keyboard.keys.BACKSPACE, altKey: null, ctrlKey: null, metaKey: null, shiftKey: null }, { collapsed: true, offset: 0 }, handleBackspace); - _this.listen(); - return _this; - } - - _createClass(Keyboard, [{ - key: 'addBinding', - value: function addBinding(key) { - var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var handler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - var binding = normalize(key); - if (binding == null || binding.key == null) { - return debug.warn('Attempted to add invalid keyboard binding', binding); - } - if (typeof context === 'function') { - context = { handler: context }; - } - if (typeof handler === 'function') { - handler = { handler: handler }; - } - binding = (0, _extend2.default)(binding, context, handler); - this.bindings[binding.key] = this.bindings[binding.key] || []; - this.bindings[binding.key].push(binding); - } - }, { - key: 'listen', - value: function listen() { - var _this2 = this; - - this.quill.root.addEventListener('keydown', function (evt) { - if (evt.defaultPrevented) return; - var which = evt.which || evt.keyCode; - var bindings = (_this2.bindings[which] || []).filter(function (binding) { - return Keyboard.match(evt, binding); - }); - if (bindings.length === 0) return; - var range = _this2.quill.getSelection(); - if (range == null || !_this2.quill.hasFocus()) return; - - var _quill$getLine = _this2.quill.getLine(range.index), - _quill$getLine2 = _slicedToArray(_quill$getLine, 2), - line = _quill$getLine2[0], - offset = _quill$getLine2[1]; - - var _quill$getLeaf = _this2.quill.getLeaf(range.index), - _quill$getLeaf2 = _slicedToArray(_quill$getLeaf, 2), - leafStart = _quill$getLeaf2[0], - offsetStart = _quill$getLeaf2[1]; - - var _ref = range.length === 0 ? [leafStart, offsetStart] : _this2.quill.getLeaf(range.index + range.length), - _ref2 = _slicedToArray(_ref, 2), - leafEnd = _ref2[0], - offsetEnd = _ref2[1]; - - var prefixText = leafStart instanceof _parchment2.default.Text ? leafStart.value().slice(0, offsetStart) : ''; - var suffixText = leafEnd instanceof _parchment2.default.Text ? leafEnd.value().slice(offsetEnd) : ''; - var curContext = { - collapsed: range.length === 0, - empty: range.length === 0 && line.length() <= 1, - format: _this2.quill.getFormat(range), - offset: offset, - prefix: prefixText, - suffix: suffixText - }; - var prevented = bindings.some(function (binding) { - if (binding.collapsed != null && binding.collapsed !== curContext.collapsed) return false; - if (binding.empty != null && binding.empty !== curContext.empty) return false; - if (binding.offset != null && binding.offset !== curContext.offset) return false; - if (Array.isArray(binding.format)) { - // any format is present - if (binding.format.every(function (name) { - return curContext.format[name] == null; - })) { - return false; - } - } else if (_typeof(binding.format) === 'object') { - // all formats must match - if (!Object.keys(binding.format).every(function (name) { - if (binding.format[name] === true) return curContext.format[name] != null; - if (binding.format[name] === false) return curContext.format[name] == null; - return (0, _deepEqual2.default)(binding.format[name], curContext.format[name]); - })) { - return false; - } - } - if (binding.prefix != null && !binding.prefix.test(curContext.prefix)) return false; - if (binding.suffix != null && !binding.suffix.test(curContext.suffix)) return false; - return binding.handler.call(_this2, range, curContext) !== true; - }); - if (prevented) { - evt.preventDefault(); - } - }); - } - }]); - - return Keyboard; -}(_module2.default); - -Keyboard.keys = { - BACKSPACE: 8, - TAB: 9, - ENTER: 13, - ESCAPE: 27, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - DELETE: 46 -}; - -Keyboard.DEFAULTS = { - bindings: { - 'bold': makeFormatHandler('bold'), - 'italic': makeFormatHandler('italic'), - 'underline': makeFormatHandler('underline'), - 'indent': { - // highlight tab or tab at beginning of list, indent or blockquote - key: Keyboard.keys.TAB, - format: ['blockquote', 'indent', 'list'], - handler: function handler(range, context) { - if (context.collapsed && context.offset !== 0) return true; - this.quill.format('indent', '+1', _quill2.default.sources.USER); - } - }, - 'outdent': { - key: Keyboard.keys.TAB, - shiftKey: true, - format: ['blockquote', 'indent', 'list'], - // highlight tab or tab at beginning of list, indent or blockquote - handler: function handler(range, context) { - if (context.collapsed && context.offset !== 0) return true; - this.quill.format('indent', '-1', _quill2.default.sources.USER); - } - }, - 'outdent backspace': { - key: Keyboard.keys.BACKSPACE, - collapsed: true, - shiftKey: null, - metaKey: null, - ctrlKey: null, - altKey: null, - format: ['indent', 'list'], - offset: 0, - handler: function handler(range, context) { - if (context.format.indent != null) { - this.quill.format('indent', '-1', _quill2.default.sources.USER); - } else if (context.format.list != null) { - this.quill.format('list', false, _quill2.default.sources.USER); - } - } - }, - 'indent code-block': makeCodeBlockHandler(true), - 'outdent code-block': makeCodeBlockHandler(false), - 'remove tab': { - key: Keyboard.keys.TAB, - shiftKey: true, - collapsed: true, - prefix: /\t$/, - handler: function handler(range) { - this.quill.deleteText(range.index - 1, 1, _quill2.default.sources.USER); - } - }, - 'tab': { - key: Keyboard.keys.TAB, - handler: function handler(range) { - this.quill.history.cutoff(); - var delta = new _quillDelta2.default().retain(range.index).delete(range.length).insert('\t'); - this.quill.updateContents(delta, _quill2.default.sources.USER); - this.quill.history.cutoff(); - this.quill.setSelection(range.index + 1, _quill2.default.sources.SILENT); - } - }, - 'list empty enter': { - key: Keyboard.keys.ENTER, - collapsed: true, - format: ['list'], - empty: true, - handler: function handler(range, context) { - this.quill.format('list', false, _quill2.default.sources.USER); - if (context.format.indent) { - this.quill.format('indent', false, _quill2.default.sources.USER); - } - } - }, - 'checklist enter': { - key: Keyboard.keys.ENTER, - collapsed: true, - format: { list: 'checked' }, - handler: function handler(range) { - var _quill$getLine3 = this.quill.getLine(range.index), - _quill$getLine4 = _slicedToArray(_quill$getLine3, 2), - line = _quill$getLine4[0], - offset = _quill$getLine4[1]; - - var formats = (0, _extend2.default)({}, line.formats(), { list: 'checked' }); - var delta = new _quillDelta2.default().retain(range.index).insert('\n', formats).retain(line.length() - offset - 1).retain(1, { list: 'unchecked' }); - this.quill.updateContents(delta, _quill2.default.sources.USER); - this.quill.setSelection(range.index + 1, _quill2.default.sources.SILENT); - this.quill.scrollIntoView(); - } - }, - 'header enter': { - key: Keyboard.keys.ENTER, - collapsed: true, - format: ['header'], - suffix: /^$/, - handler: function handler(range, context) { - var _quill$getLine5 = this.quill.getLine(range.index), - _quill$getLine6 = _slicedToArray(_quill$getLine5, 2), - line = _quill$getLine6[0], - offset = _quill$getLine6[1]; - - var delta = new _quillDelta2.default().retain(range.index).insert('\n', context.format).retain(line.length() - offset - 1).retain(1, { header: null }); - this.quill.updateContents(delta, _quill2.default.sources.USER); - this.quill.setSelection(range.index + 1, _quill2.default.sources.SILENT); - this.quill.scrollIntoView(); - } - }, - 'list autofill': { - key: ' ', - collapsed: true, - format: { list: false }, - prefix: /^\s*?(\d+\.|-|\*|\[ ?\]|\[x\])$/, - handler: function handler(range, context) { - var length = context.prefix.length; - - var _quill$getLine7 = this.quill.getLine(range.index), - _quill$getLine8 = _slicedToArray(_quill$getLine7, 2), - line = _quill$getLine8[0], - offset = _quill$getLine8[1]; - - if (offset > length) return true; - var value = void 0; - switch (context.prefix.trim()) { - case '[]':case '[ ]': - value = 'unchecked'; - break; - case '[x]': - value = 'checked'; - break; - case '-':case '*': - value = 'bullet'; - break; - default: - value = 'ordered'; - } - this.quill.insertText(range.index, ' ', _quill2.default.sources.USER); - this.quill.history.cutoff(); - var delta = new _quillDelta2.default().retain(range.index - offset).delete(length + 1).retain(line.length() - 2 - offset).retain(1, { list: value }); - this.quill.updateContents(delta, _quill2.default.sources.USER); - this.quill.history.cutoff(); - this.quill.setSelection(range.index - length, _quill2.default.sources.SILENT); - } - }, - 'code exit': { - key: Keyboard.keys.ENTER, - collapsed: true, - format: ['code-block'], - prefix: /\n\n$/, - suffix: /^\s+$/, - handler: function handler(range) { - var _quill$getLine9 = this.quill.getLine(range.index), - _quill$getLine10 = _slicedToArray(_quill$getLine9, 2), - line = _quill$getLine10[0], - offset = _quill$getLine10[1]; - - var delta = new _quillDelta2.default().retain(range.index + line.length() - offset - 2).retain(1, { 'code-block': null }).delete(1); - this.quill.updateContents(delta, _quill2.default.sources.USER); - } - }, - 'embed left': makeEmbedArrowHandler(Keyboard.keys.LEFT, false), - 'embed left shift': makeEmbedArrowHandler(Keyboard.keys.LEFT, true), - 'embed right': makeEmbedArrowHandler(Keyboard.keys.RIGHT, false), - 'embed right shift': makeEmbedArrowHandler(Keyboard.keys.RIGHT, true) - } -}; - -function makeEmbedArrowHandler(key, shiftKey) { - var _ref3; - - var where = key === Keyboard.keys.LEFT ? 'prefix' : 'suffix'; - return _ref3 = { - key: key, - shiftKey: shiftKey, - altKey: null - }, _defineProperty(_ref3, where, /^$/), _defineProperty(_ref3, 'handler', function handler(range) { - var index = range.index; - if (key === Keyboard.keys.RIGHT) { - index += range.length + 1; - } - - var _quill$getLeaf3 = this.quill.getLeaf(index), - _quill$getLeaf4 = _slicedToArray(_quill$getLeaf3, 1), - leaf = _quill$getLeaf4[0]; - - if (!(leaf instanceof _parchment2.default.Embed)) return true; - if (key === Keyboard.keys.LEFT) { - if (shiftKey) { - this.quill.setSelection(range.index - 1, range.length + 1, _quill2.default.sources.USER); - } else { - this.quill.setSelection(range.index - 1, _quill2.default.sources.USER); - } - } else { - if (shiftKey) { - this.quill.setSelection(range.index, range.length + 1, _quill2.default.sources.USER); - } else { - this.quill.setSelection(range.index + range.length + 1, _quill2.default.sources.USER); - } - } - return false; - }), _ref3; -} - -function handleBackspace(range, context) { - if (range.index === 0 || this.quill.getLength() <= 1) return; - - var _quill$getLine11 = this.quill.getLine(range.index), - _quill$getLine12 = _slicedToArray(_quill$getLine11, 1), - line = _quill$getLine12[0]; - - var formats = {}; - if (context.offset === 0) { - var _quill$getLine13 = this.quill.getLine(range.index - 1), - _quill$getLine14 = _slicedToArray(_quill$getLine13, 1), - prev = _quill$getLine14[0]; - - if (prev != null && prev.length() > 1) { - var curFormats = line.formats(); - var prevFormats = this.quill.getFormat(range.index - 1, 1); - formats = _op2.default.attributes.diff(curFormats, prevFormats) || {}; - } - } - // Check for astral symbols - var length = /[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test(context.prefix) ? 2 : 1; - this.quill.deleteText(range.index - length, length, _quill2.default.sources.USER); - if (Object.keys(formats).length > 0) { - this.quill.formatLine(range.index - length, length, formats, _quill2.default.sources.USER); - } - this.quill.focus(); -} - -function handleDelete(range, context) { - // Check for astral symbols - var length = /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(context.suffix) ? 2 : 1; - if (range.index >= this.quill.getLength() - length) return; - var formats = {}, - nextLength = 0; - - var _quill$getLine15 = this.quill.getLine(range.index), - _quill$getLine16 = _slicedToArray(_quill$getLine15, 1), - line = _quill$getLine16[0]; - - if (context.offset >= line.length() - 1) { - var _quill$getLine17 = this.quill.getLine(range.index + 1), - _quill$getLine18 = _slicedToArray(_quill$getLine17, 1), - next = _quill$getLine18[0]; - - if (next) { - var curFormats = line.formats(); - var nextFormats = this.quill.getFormat(range.index, 1); - formats = _op2.default.attributes.diff(curFormats, nextFormats) || {}; - nextLength = next.length(); - } - } - this.quill.deleteText(range.index, length, _quill2.default.sources.USER); - if (Object.keys(formats).length > 0) { - this.quill.formatLine(range.index + nextLength - 1, length, formats, _quill2.default.sources.USER); - } -} - -function handleDeleteRange(range) { - var lines = this.quill.getLines(range); - var formats = {}; - if (lines.length > 1) { - var firstFormats = lines[0].formats(); - var lastFormats = lines[lines.length - 1].formats(); - formats = _op2.default.attributes.diff(lastFormats, firstFormats) || {}; - } - this.quill.deleteText(range, _quill2.default.sources.USER); - if (Object.keys(formats).length > 0) { - this.quill.formatLine(range.index, 1, formats, _quill2.default.sources.USER); - } - this.quill.setSelection(range.index, _quill2.default.sources.SILENT); - this.quill.focus(); -} - -function handleEnter(range, context) { - var _this3 = this; - - if (range.length > 0) { - this.quill.scroll.deleteAt(range.index, range.length); // So we do not trigger text-change - } - var lineFormats = Object.keys(context.format).reduce(function (lineFormats, format) { - if (_parchment2.default.query(format, _parchment2.default.Scope.BLOCK) && !Array.isArray(context.format[format])) { - lineFormats[format] = context.format[format]; - } - return lineFormats; - }, {}); - this.quill.insertText(range.index, '\n', lineFormats, _quill2.default.sources.USER); - // Earlier scroll.deleteAt might have messed up our selection, - // so insertText's built in selection preservation is not reliable - this.quill.setSelection(range.index + 1, _quill2.default.sources.SILENT); - this.quill.focus(); - Object.keys(context.format).forEach(function (name) { - if (lineFormats[name] != null) return; - if (Array.isArray(context.format[name])) return; - if (name === 'link') return; - _this3.quill.format(name, context.format[name], _quill2.default.sources.USER); - }); -} - -function makeCodeBlockHandler(indent) { - return { - key: Keyboard.keys.TAB, - shiftKey: !indent, - format: { 'code-block': true }, - handler: function handler(range) { - var CodeBlock = _parchment2.default.query('code-block'); - var index = range.index, - length = range.length; - - var _quill$scroll$descend = this.quill.scroll.descendant(CodeBlock, index), - _quill$scroll$descend2 = _slicedToArray(_quill$scroll$descend, 2), - block = _quill$scroll$descend2[0], - offset = _quill$scroll$descend2[1]; - - if (block == null) return; - var scrollIndex = this.quill.getIndex(block); - var start = block.newlineIndex(offset, true) + 1; - var end = block.newlineIndex(scrollIndex + offset + length); - var lines = block.domNode.textContent.slice(start, end).split('\n'); - offset = 0; - lines.forEach(function (line, i) { - if (indent) { - block.insertAt(start + offset, CodeBlock.TAB); - offset += CodeBlock.TAB.length; - if (i === 0) { - index += CodeBlock.TAB.length; - } else { - length += CodeBlock.TAB.length; - } - } else if (line.startsWith(CodeBlock.TAB)) { - block.deleteAt(start + offset, CodeBlock.TAB.length); - offset -= CodeBlock.TAB.length; - if (i === 0) { - index -= CodeBlock.TAB.length; - } else { - length -= CodeBlock.TAB.length; - } - } - offset += line.length + 1; - }); - this.quill.update(_quill2.default.sources.USER); - this.quill.setSelection(index, length, _quill2.default.sources.SILENT); - } - }; -} - -function makeFormatHandler(format) { - return { - key: format[0].toUpperCase(), - shortKey: true, - handler: function handler(range, context) { - this.quill.format(format, !context.format[format], _quill2.default.sources.USER); - } - }; -} - -function normalize(binding) { - if (typeof binding === 'string' || typeof binding === 'number') { - return normalize({ key: binding }); - } - if ((typeof binding === 'undefined' ? 'undefined' : _typeof(binding)) === 'object') { - binding = (0, _clone2.default)(binding, false); - } - if (typeof binding.key === 'string') { - if (Keyboard.keys[binding.key.toUpperCase()] != null) { - binding.key = Keyboard.keys[binding.key.toUpperCase()]; - } else if (binding.key.length === 1) { - binding.key = binding.key.toUpperCase().charCodeAt(0); - } else { - return null; - } - } - if (binding.shortKey) { - binding[SHORTKEY] = binding.shortKey; - delete binding.shortKey; - } - return binding; -} - -exports.default = Keyboard; -exports.SHORTKEY = SHORTKEY; - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _text = __webpack_require__(7); - -var _text2 = _interopRequireDefault(_text); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Cursor = function (_Parchment$Embed) { - _inherits(Cursor, _Parchment$Embed); - - _createClass(Cursor, null, [{ - key: 'value', - value: function value() { - return undefined; - } - }]); - - function Cursor(domNode, selection) { - _classCallCheck(this, Cursor); - - var _this = _possibleConstructorReturn(this, (Cursor.__proto__ || Object.getPrototypeOf(Cursor)).call(this, domNode)); - - _this.selection = selection; - _this.textNode = document.createTextNode(Cursor.CONTENTS); - _this.domNode.appendChild(_this.textNode); - _this._length = 0; - return _this; - } - - _createClass(Cursor, [{ - key: 'detach', - value: function detach() { - // super.detach() will also clear domNode.__blot - if (this.parent != null) this.parent.removeChild(this); - } - }, { - key: 'format', - value: function format(name, value) { - if (this._length !== 0) { - return _get(Cursor.prototype.__proto__ || Object.getPrototypeOf(Cursor.prototype), 'format', this).call(this, name, value); - } - var target = this, - index = 0; - while (target != null && target.statics.scope !== _parchment2.default.Scope.BLOCK_BLOT) { - index += target.offset(target.parent); - target = target.parent; - } - if (target != null) { - this._length = Cursor.CONTENTS.length; - target.optimize(); - target.formatAt(index, Cursor.CONTENTS.length, name, value); - this._length = 0; - } - } - }, { - key: 'index', - value: function index(node, offset) { - if (node === this.textNode) return 0; - return _get(Cursor.prototype.__proto__ || Object.getPrototypeOf(Cursor.prototype), 'index', this).call(this, node, offset); - } - }, { - key: 'length', - value: function length() { - return this._length; - } - }, { - key: 'position', - value: function position() { - return [this.textNode, this.textNode.data.length]; - } - }, { - key: 'remove', - value: function remove() { - _get(Cursor.prototype.__proto__ || Object.getPrototypeOf(Cursor.prototype), 'remove', this).call(this); - this.parent = null; - } - }, { - key: 'restore', - value: function restore() { - if (this.selection.composing || this.parent == null) return; - var textNode = this.textNode; - var range = this.selection.getNativeRange(); - var restoreText = void 0, - start = void 0, - end = void 0; - if (range != null && range.start.node === textNode && range.end.node === textNode) { - var _ref = [textNode, range.start.offset, range.end.offset]; - restoreText = _ref[0]; - start = _ref[1]; - end = _ref[2]; - } - // Link format will insert text outside of anchor tag - while (this.domNode.lastChild != null && this.domNode.lastChild !== this.textNode) { - this.domNode.parentNode.insertBefore(this.domNode.lastChild, this.domNode); - } - if (this.textNode.data !== Cursor.CONTENTS) { - var text = this.textNode.data.split(Cursor.CONTENTS).join(''); - if (this.next instanceof _text2.default) { - restoreText = this.next.domNode; - this.next.insertAt(0, text); - this.textNode.data = Cursor.CONTENTS; - } else { - this.textNode.data = text; - this.parent.insertBefore(_parchment2.default.create(this.textNode), this); - this.textNode = document.createTextNode(Cursor.CONTENTS); - this.domNode.appendChild(this.textNode); - } - } - this.remove(); - if (start != null) { - var _map = [start, end].map(function (offset) { - return Math.max(0, Math.min(restoreText.data.length, offset - 1)); - }); - - var _map2 = _slicedToArray(_map, 2); - - start = _map2[0]; - end = _map2[1]; - - return { - startNode: restoreText, - startOffset: start, - endNode: restoreText, - endOffset: end - }; - } - } - }, { - key: 'update', - value: function update(mutations, context) { - var _this2 = this; - - if (mutations.some(function (mutation) { - return mutation.type === 'characterData' && mutation.target === _this2.textNode; - })) { - var range = this.restore(); - if (range) context.range = range; - } - } - }, { - key: 'value', - value: function value() { - return ''; - } - }]); - - return Cursor; -}(_parchment2.default.Embed); - -Cursor.blotName = 'cursor'; -Cursor.className = 'ql-cursor'; -Cursor.tagName = 'span'; -Cursor.CONTENTS = '\uFEFF'; // Zero width no break space - - -exports.default = Cursor; - -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _block = __webpack_require__(4); - -var _block2 = _interopRequireDefault(_block); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Container = function (_Parchment$Container) { - _inherits(Container, _Parchment$Container); - - function Container() { - _classCallCheck(this, Container); - - return _possibleConstructorReturn(this, (Container.__proto__ || Object.getPrototypeOf(Container)).apply(this, arguments)); - } - - return Container; -}(_parchment2.default.Container); - -Container.allowedChildren = [_block2.default, _block.BlockEmbed, Container]; - -exports.default = Container; - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ColorStyle = exports.ColorClass = exports.ColorAttributor = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var ColorAttributor = function (_Parchment$Attributor) { - _inherits(ColorAttributor, _Parchment$Attributor); - - function ColorAttributor() { - _classCallCheck(this, ColorAttributor); - - return _possibleConstructorReturn(this, (ColorAttributor.__proto__ || Object.getPrototypeOf(ColorAttributor)).apply(this, arguments)); - } - - _createClass(ColorAttributor, [{ - key: 'value', - value: function value(domNode) { - var value = _get(ColorAttributor.prototype.__proto__ || Object.getPrototypeOf(ColorAttributor.prototype), 'value', this).call(this, domNode); - if (!value.startsWith('rgb(')) return value; - value = value.replace(/^[^\d]+/, '').replace(/[^\d]+$/, ''); - return '#' + value.split(',').map(function (component) { - return ('00' + parseInt(component).toString(16)).slice(-2); - }).join(''); - } - }]); - - return ColorAttributor; -}(_parchment2.default.Attributor.Style); - -var ColorClass = new _parchment2.default.Attributor.Class('color', 'ql-color', { - scope: _parchment2.default.Scope.INLINE -}); -var ColorStyle = new ColorAttributor('color', 'color', { - scope: _parchment2.default.Scope.INLINE -}); - -exports.ColorAttributor = ColorAttributor; -exports.ColorClass = ColorClass; -exports.ColorStyle = ColorStyle; - -/***/ }), -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.sanitize = exports.default = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _inline = __webpack_require__(6); - -var _inline2 = _interopRequireDefault(_inline); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Link = function (_Inline) { - _inherits(Link, _Inline); - - function Link() { - _classCallCheck(this, Link); - - return _possibleConstructorReturn(this, (Link.__proto__ || Object.getPrototypeOf(Link)).apply(this, arguments)); - } - - _createClass(Link, [{ - key: 'format', - value: function format(name, value) { - if (name !== this.statics.blotName || !value) return _get(Link.prototype.__proto__ || Object.getPrototypeOf(Link.prototype), 'format', this).call(this, name, value); - value = this.constructor.sanitize(value); - this.domNode.setAttribute('href', value); - } - }], [{ - key: 'create', - value: function create(value) { - var node = _get(Link.__proto__ || Object.getPrototypeOf(Link), 'create', this).call(this, value); - value = this.sanitize(value); - node.setAttribute('href', value); - // node.setAttribute('rel', 'noopener noreferrer'); - // node.setAttribute('target', '_blank'); - return node; - } - }, { - key: 'formats', - value: function formats(domNode) { - return domNode.getAttribute('href'); - } - }, { - key: 'sanitize', - value: function sanitize(url) { - return _sanitize(url, this.PROTOCOL_WHITELIST) ? url : this.SANITIZED_URL; - } - }]); - - return Link; -}(_inline2.default); - -Link.blotName = 'link'; -Link.tagName = 'A'; -Link.SANITIZED_URL = 'about:blank'; -Link.PROTOCOL_WHITELIST = ['http', 'https', 'mailto', 'tel']; - -function _sanitize(url, protocols) { - var anchor = document.createElement('a'); - anchor.href = url; - var protocol = anchor.href.slice(0, anchor.href.indexOf(':')); - return protocols.indexOf(protocol) > -1; -} - -exports.default = Link; -exports.sanitize = _sanitize; - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _keyboard = __webpack_require__(23); - -var _keyboard2 = _interopRequireDefault(_keyboard); - -var _dropdown = __webpack_require__(107); - -var _dropdown2 = _interopRequireDefault(_dropdown); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var optionsCounter = 0; - -function toggleAriaAttribute(element, attribute) { - element.setAttribute(attribute, !(element.getAttribute(attribute) === 'true')); -} - -var Picker = function () { - function Picker(select) { - var _this = this; - - _classCallCheck(this, Picker); - - this.select = select; - this.container = document.createElement('span'); - this.buildPicker(); - this.select.style.display = 'none'; - this.select.parentNode.insertBefore(this.container, this.select); - - this.label.addEventListener('mousedown', function () { - _this.togglePicker(); - }); - this.label.addEventListener('keydown', function (event) { - switch (event.keyCode) { - // Allows the "Enter" key to open the picker - case _keyboard2.default.keys.ENTER: - _this.togglePicker(); - break; - - // Allows the "Escape" key to close the picker - case _keyboard2.default.keys.ESCAPE: - _this.escape(); - event.preventDefault(); - break; - default: - } - }); - this.select.addEventListener('change', this.update.bind(this)); - } - - _createClass(Picker, [{ - key: 'togglePicker', - value: function togglePicker() { - this.container.classList.toggle('ql-expanded'); - // Toggle aria-expanded and aria-hidden to make the picker accessible - toggleAriaAttribute(this.label, 'aria-expanded'); - toggleAriaAttribute(this.options, 'aria-hidden'); - } - }, { - key: 'buildItem', - value: function buildItem(option) { - var _this2 = this; - - var item = document.createElement('span'); - item.tabIndex = '0'; - item.setAttribute('role', 'button'); - - item.classList.add('ql-picker-item'); - if (option.hasAttribute('value')) { - item.setAttribute('data-value', option.getAttribute('value')); - } - if (option.textContent) { - item.setAttribute('data-label', option.textContent); - } - item.addEventListener('click', function () { - _this2.selectItem(item, true); - }); - item.addEventListener('keydown', function (event) { - switch (event.keyCode) { - // Allows the "Enter" key to select an item - case _keyboard2.default.keys.ENTER: - _this2.selectItem(item, true); - event.preventDefault(); - break; - - // Allows the "Escape" key to close the picker - case _keyboard2.default.keys.ESCAPE: - _this2.escape(); - event.preventDefault(); - break; - default: - } - }); - - return item; - } - }, { - key: 'buildLabel', - value: function buildLabel() { - var label = document.createElement('span'); - label.classList.add('ql-picker-label'); - label.innerHTML = _dropdown2.default; - label.tabIndex = '0'; - label.setAttribute('role', 'button'); - label.setAttribute('aria-expanded', 'false'); - this.container.appendChild(label); - return label; - } - }, { - key: 'buildOptions', - value: function buildOptions() { - var _this3 = this; - - var options = document.createElement('span'); - options.classList.add('ql-picker-options'); - - // Don't want screen readers to read this until options are visible - options.setAttribute('aria-hidden', 'true'); - options.tabIndex = '-1'; - - // Need a unique id for aria-controls - options.id = 'ql-picker-options-' + optionsCounter; - optionsCounter += 1; - this.label.setAttribute('aria-controls', options.id); - - this.options = options; - - [].slice.call(this.select.options).forEach(function (option) { - var item = _this3.buildItem(option); - options.appendChild(item); - if (option.selected === true) { - _this3.selectItem(item); - } - }); - this.container.appendChild(options); - } - }, { - key: 'buildPicker', - value: function buildPicker() { - var _this4 = this; - - [].slice.call(this.select.attributes).forEach(function (item) { - _this4.container.setAttribute(item.name, item.value); - }); - this.container.classList.add('ql-picker'); - this.label = this.buildLabel(); - this.buildOptions(); - } - }, { - key: 'escape', - value: function escape() { - var _this5 = this; - - // Close menu and return focus to trigger label - this.close(); - // Need setTimeout for accessibility to ensure that the browser executes - // focus on the next process thread and after any DOM content changes - setTimeout(function () { - return _this5.label.focus(); - }, 1); - } - }, { - key: 'close', - value: function close() { - this.container.classList.remove('ql-expanded'); - this.label.setAttribute('aria-expanded', 'false'); - this.options.setAttribute('aria-hidden', 'true'); - } - }, { - key: 'selectItem', - value: function selectItem(item) { - var trigger = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - var selected = this.container.querySelector('.ql-selected'); - if (item === selected) return; - if (selected != null) { - selected.classList.remove('ql-selected'); - } - if (item == null) return; - item.classList.add('ql-selected'); - this.select.selectedIndex = [].indexOf.call(item.parentNode.children, item); - if (item.hasAttribute('data-value')) { - this.label.setAttribute('data-value', item.getAttribute('data-value')); - } else { - this.label.removeAttribute('data-value'); - } - if (item.hasAttribute('data-label')) { - this.label.setAttribute('data-label', item.getAttribute('data-label')); - } else { - this.label.removeAttribute('data-label'); - } - if (trigger) { - if (typeof Event === 'function') { - this.select.dispatchEvent(new Event('change')); - } else if ((typeof Event === 'undefined' ? 'undefined' : _typeof(Event)) === 'object') { - // IE11 - var event = document.createEvent('Event'); - event.initEvent('change', true, true); - this.select.dispatchEvent(event); - } - this.close(); - } - } - }, { - key: 'update', - value: function update() { - var option = void 0; - if (this.select.selectedIndex > -1) { - var item = this.container.querySelector('.ql-picker-options').children[this.select.selectedIndex]; - option = this.select.options[this.select.selectedIndex]; - this.selectItem(item); - } else { - this.selectItem(null); - } - var isActive = option != null && option !== this.select.querySelector('option[selected]'); - this.label.classList.toggle('ql-active', isActive); - } - }]); - - return Picker; -}(); - -exports.default = Picker; - -/***/ }), -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _quill = __webpack_require__(5); - -var _quill2 = _interopRequireDefault(_quill); - -var _block = __webpack_require__(4); - -var _block2 = _interopRequireDefault(_block); - -var _break = __webpack_require__(16); - -var _break2 = _interopRequireDefault(_break); - -var _container = __webpack_require__(25); - -var _container2 = _interopRequireDefault(_container); - -var _cursor = __webpack_require__(24); - -var _cursor2 = _interopRequireDefault(_cursor); - -var _embed = __webpack_require__(35); - -var _embed2 = _interopRequireDefault(_embed); - -var _inline = __webpack_require__(6); - -var _inline2 = _interopRequireDefault(_inline); - -var _scroll = __webpack_require__(22); - -var _scroll2 = _interopRequireDefault(_scroll); - -var _text = __webpack_require__(7); - -var _text2 = _interopRequireDefault(_text); - -var _clipboard = __webpack_require__(55); - -var _clipboard2 = _interopRequireDefault(_clipboard); - -var _history = __webpack_require__(42); - -var _history2 = _interopRequireDefault(_history); - -var _keyboard = __webpack_require__(23); - -var _keyboard2 = _interopRequireDefault(_keyboard); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -_quill2.default.register({ - 'blots/block': _block2.default, - 'blots/block/embed': _block.BlockEmbed, - 'blots/break': _break2.default, - 'blots/container': _container2.default, - 'blots/cursor': _cursor2.default, - 'blots/embed': _embed2.default, - 'blots/inline': _inline2.default, - 'blots/scroll': _scroll2.default, - 'blots/text': _text2.default, - - 'modules/clipboard': _clipboard2.default, - 'modules/history': _history2.default, - 'modules/keyboard': _keyboard2.default -}); - -_parchment2.default.register(_block2.default, _break2.default, _cursor2.default, _inline2.default, _scroll2.default, _text2.default); - -exports.default = _quill2.default; - -/***/ }), -/* 30 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var Registry = __webpack_require__(1); -var ShadowBlot = /** @class */ (function () { - function ShadowBlot(domNode) { - this.domNode = domNode; - // @ts-ignore - this.domNode[Registry.DATA_KEY] = { blot: this }; - } - Object.defineProperty(ShadowBlot.prototype, "statics", { - // Hack for accessing inherited static methods - get: function () { - return this.constructor; - }, - enumerable: true, - configurable: true - }); - ShadowBlot.create = function (value) { - if (this.tagName == null) { - throw new Registry.ParchmentError('Blot definition missing tagName'); - } - var node; - if (Array.isArray(this.tagName)) { - if (typeof value === 'string') { - value = value.toUpperCase(); - if (parseInt(value).toString() === value) { - value = parseInt(value); - } - } - if (typeof value === 'number') { - node = document.createElement(this.tagName[value - 1]); - } - else if (this.tagName.indexOf(value) > -1) { - node = document.createElement(value); - } - else { - node = document.createElement(this.tagName[0]); - } - } - else { - node = document.createElement(this.tagName); - } - if (this.className) { - node.classList.add(this.className); - } - return node; - }; - ShadowBlot.prototype.attach = function () { - if (this.parent != null) { - this.scroll = this.parent.scroll; - } - }; - ShadowBlot.prototype.clone = function () { - var domNode = this.domNode.cloneNode(false); - return Registry.create(domNode); - }; - ShadowBlot.prototype.detach = function () { - if (this.parent != null) - this.parent.removeChild(this); - // @ts-ignore - delete this.domNode[Registry.DATA_KEY]; - }; - ShadowBlot.prototype.deleteAt = function (index, length) { - var blot = this.isolate(index, length); - blot.remove(); - }; - ShadowBlot.prototype.formatAt = function (index, length, name, value) { - var blot = this.isolate(index, length); - if (Registry.query(name, Registry.Scope.BLOT) != null && value) { - blot.wrap(name, value); - } - else if (Registry.query(name, Registry.Scope.ATTRIBUTE) != null) { - var parent = Registry.create(this.statics.scope); - blot.wrap(parent); - parent.format(name, value); - } - }; - ShadowBlot.prototype.insertAt = function (index, value, def) { - var blot = def == null ? Registry.create('text', value) : Registry.create(value, def); - var ref = this.split(index); - this.parent.insertBefore(blot, ref); - }; - ShadowBlot.prototype.insertInto = function (parentBlot, refBlot) { - if (refBlot === void 0) { refBlot = null; } - if (this.parent != null) { - this.parent.children.remove(this); - } - var refDomNode = null; - parentBlot.children.insertBefore(this, refBlot); - if (refBlot != null) { - refDomNode = refBlot.domNode; - } - if (this.domNode.parentNode != parentBlot.domNode || - this.domNode.nextSibling != refDomNode) { - parentBlot.domNode.insertBefore(this.domNode, refDomNode); - } - this.parent = parentBlot; - this.attach(); - }; - ShadowBlot.prototype.isolate = function (index, length) { - var target = this.split(index); - target.split(length); - return target; - }; - ShadowBlot.prototype.length = function () { - return 1; - }; - ShadowBlot.prototype.offset = function (root) { - if (root === void 0) { root = this.parent; } - if (this.parent == null || this == root) - return 0; - return this.parent.children.offset(this) + this.parent.offset(root); - }; - ShadowBlot.prototype.optimize = function (context) { - // TODO clean up once we use WeakMap - // @ts-ignore - if (this.domNode[Registry.DATA_KEY] != null) { - // @ts-ignore - delete this.domNode[Registry.DATA_KEY].mutations; - } - }; - ShadowBlot.prototype.remove = function () { - if (this.domNode.parentNode != null) { - this.domNode.parentNode.removeChild(this.domNode); - } - this.detach(); - }; - ShadowBlot.prototype.replace = function (target) { - if (target.parent == null) - return; - target.parent.insertBefore(this, target.next); - target.remove(); - }; - ShadowBlot.prototype.replaceWith = function (name, value) { - var replacement = typeof name === 'string' ? Registry.create(name, value) : name; - replacement.replace(this); - return replacement; - }; - ShadowBlot.prototype.split = function (index, force) { - return index === 0 ? this : this.next; - }; - ShadowBlot.prototype.update = function (mutations, context) { - // Nothing to do by default - }; - ShadowBlot.prototype.wrap = function (name, value) { - var wrapper = typeof name === 'string' ? Registry.create(name, value) : name; - if (this.parent != null) { - this.parent.insertBefore(wrapper, this.next); - } - wrapper.appendChild(this); - return wrapper; - }; - ShadowBlot.blotName = 'abstract'; - return ShadowBlot; -}()); -exports.default = ShadowBlot; - - -/***/ }), -/* 31 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var attributor_1 = __webpack_require__(12); -var class_1 = __webpack_require__(32); -var style_1 = __webpack_require__(33); -var Registry = __webpack_require__(1); -var AttributorStore = /** @class */ (function () { - function AttributorStore(domNode) { - this.attributes = {}; - this.domNode = domNode; - this.build(); - } - AttributorStore.prototype.attribute = function (attribute, value) { - // verb - if (value) { - if (attribute.add(this.domNode, value)) { - if (attribute.value(this.domNode) != null) { - this.attributes[attribute.attrName] = attribute; - } - else { - delete this.attributes[attribute.attrName]; - } - } - } - else { - attribute.remove(this.domNode); - delete this.attributes[attribute.attrName]; - } - }; - AttributorStore.prototype.build = function () { - var _this = this; - this.attributes = {}; - var attributes = attributor_1.default.keys(this.domNode); - var classes = class_1.default.keys(this.domNode); - var styles = style_1.default.keys(this.domNode); - attributes - .concat(classes) - .concat(styles) - .forEach(function (name) { - var attr = Registry.query(name, Registry.Scope.ATTRIBUTE); - if (attr instanceof attributor_1.default) { - _this.attributes[attr.attrName] = attr; - } - }); - }; - AttributorStore.prototype.copy = function (target) { - var _this = this; - Object.keys(this.attributes).forEach(function (key) { - var value = _this.attributes[key].value(_this.domNode); - target.format(key, value); - }); - }; - AttributorStore.prototype.move = function (target) { - var _this = this; - this.copy(target); - Object.keys(this.attributes).forEach(function (key) { - _this.attributes[key].remove(_this.domNode); - }); - this.attributes = {}; - }; - AttributorStore.prototype.values = function () { - var _this = this; - return Object.keys(this.attributes).reduce(function (attributes, name) { - attributes[name] = _this.attributes[name].value(_this.domNode); - return attributes; - }, {}); - }; - return AttributorStore; -}()); -exports.default = AttributorStore; - - -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var attributor_1 = __webpack_require__(12); -function match(node, prefix) { - var className = node.getAttribute('class') || ''; - return className.split(/\s+/).filter(function (name) { - return name.indexOf(prefix + "-") === 0; - }); -} -var ClassAttributor = /** @class */ (function (_super) { - __extends(ClassAttributor, _super); - function ClassAttributor() { - return _super !== null && _super.apply(this, arguments) || this; - } - ClassAttributor.keys = function (node) { - return (node.getAttribute('class') || '').split(/\s+/).map(function (name) { - return name - .split('-') - .slice(0, -1) - .join('-'); - }); - }; - ClassAttributor.prototype.add = function (node, value) { - if (!this.canAdd(node, value)) - return false; - this.remove(node); - node.classList.add(this.keyName + "-" + value); - return true; - }; - ClassAttributor.prototype.remove = function (node) { - var matches = match(node, this.keyName); - matches.forEach(function (name) { - node.classList.remove(name); - }); - if (node.classList.length === 0) { - node.removeAttribute('class'); - } - }; - ClassAttributor.prototype.value = function (node) { - var result = match(node, this.keyName)[0] || ''; - var value = result.slice(this.keyName.length + 1); // +1 for hyphen - return this.canAdd(node, value) ? value : ''; - }; - return ClassAttributor; -}(attributor_1.default)); -exports.default = ClassAttributor; - - -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var attributor_1 = __webpack_require__(12); -function camelize(name) { - var parts = name.split('-'); - var rest = parts - .slice(1) - .map(function (part) { - return part[0].toUpperCase() + part.slice(1); - }) - .join(''); - return parts[0] + rest; -} -var StyleAttributor = /** @class */ (function (_super) { - __extends(StyleAttributor, _super); - function StyleAttributor() { - return _super !== null && _super.apply(this, arguments) || this; - } - StyleAttributor.keys = function (node) { - return (node.getAttribute('style') || '').split(';').map(function (value) { - var arr = value.split(':'); - return arr[0].trim(); - }); - }; - StyleAttributor.prototype.add = function (node, value) { - if (!this.canAdd(node, value)) - return false; - // @ts-ignore - node.style[camelize(this.keyName)] = value; - return true; - }; - StyleAttributor.prototype.remove = function (node) { - // @ts-ignore - node.style[camelize(this.keyName)] = ''; - if (!node.getAttribute('style')) { - node.removeAttribute('style'); - } - }; - StyleAttributor.prototype.value = function (node) { - // @ts-ignore - var value = node.style[camelize(this.keyName)]; - return this.canAdd(node, value) ? value : ''; - }; - return StyleAttributor; -}(attributor_1.default)); -exports.default = StyleAttributor; - - -/***/ }), -/* 34 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Theme = function () { - function Theme(quill, options) { - _classCallCheck(this, Theme); - - this.quill = quill; - this.options = options; - this.modules = {}; - } - - _createClass(Theme, [{ - key: 'init', - value: function init() { - var _this = this; - - Object.keys(this.options.modules).forEach(function (name) { - if (_this.modules[name] == null) { - _this.addModule(name); - } - }); - } - }, { - key: 'addModule', - value: function addModule(name) { - var moduleClass = this.quill.constructor.import('modules/' + name); - this.modules[name] = new moduleClass(this.quill, this.options.modules[name] || {}); - return this.modules[name]; - } - }]); - - return Theme; -}(); - -Theme.DEFAULTS = { - modules: {} -}; -Theme.themes = { - 'default': Theme -}; - -exports.default = Theme; - -/***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _text = __webpack_require__(7); - -var _text2 = _interopRequireDefault(_text); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var GUARD_TEXT = '\uFEFF'; - -var Embed = function (_Parchment$Embed) { - _inherits(Embed, _Parchment$Embed); - - function Embed(node) { - _classCallCheck(this, Embed); - - var _this = _possibleConstructorReturn(this, (Embed.__proto__ || Object.getPrototypeOf(Embed)).call(this, node)); - - _this.contentNode = document.createElement('span'); - _this.contentNode.setAttribute('contenteditable', false); - [].slice.call(_this.domNode.childNodes).forEach(function (childNode) { - _this.contentNode.appendChild(childNode); - }); - _this.leftGuard = document.createTextNode(GUARD_TEXT); - _this.rightGuard = document.createTextNode(GUARD_TEXT); - _this.domNode.appendChild(_this.leftGuard); - _this.domNode.appendChild(_this.contentNode); - _this.domNode.appendChild(_this.rightGuard); - return _this; - } - - _createClass(Embed, [{ - key: 'index', - value: function index(node, offset) { - if (node === this.leftGuard) return 0; - if (node === this.rightGuard) return 1; - return _get(Embed.prototype.__proto__ || Object.getPrototypeOf(Embed.prototype), 'index', this).call(this, node, offset); - } - }, { - key: 'restore', - value: function restore(node) { - var range = void 0, - textNode = void 0; - var text = node.data.split(GUARD_TEXT).join(''); - if (node === this.leftGuard) { - if (this.prev instanceof _text2.default) { - var prevLength = this.prev.length(); - this.prev.insertAt(prevLength, text); - range = { - startNode: this.prev.domNode, - startOffset: prevLength + text.length - }; - } else { - textNode = document.createTextNode(text); - this.parent.insertBefore(_parchment2.default.create(textNode), this); - range = { - startNode: textNode, - startOffset: text.length - }; - } - } else if (node === this.rightGuard) { - if (this.next instanceof _text2.default) { - this.next.insertAt(0, text); - range = { - startNode: this.next.domNode, - startOffset: text.length - }; - } else { - textNode = document.createTextNode(text); - this.parent.insertBefore(_parchment2.default.create(textNode), this.next); - range = { - startNode: textNode, - startOffset: text.length - }; - } - } - node.data = GUARD_TEXT; - return range; - } - }, { - key: 'update', - value: function update(mutations, context) { - var _this2 = this; - - mutations.forEach(function (mutation) { - if (mutation.type === 'characterData' && (mutation.target === _this2.leftGuard || mutation.target === _this2.rightGuard)) { - var range = _this2.restore(mutation.target); - if (range) context.range = range; - } - }); - } - }]); - - return Embed; -}(_parchment2.default.Embed); - -exports.default = Embed; - -/***/ }), -/* 36 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.AlignStyle = exports.AlignClass = exports.AlignAttribute = undefined; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var config = { - scope: _parchment2.default.Scope.BLOCK, - whitelist: ['right', 'center', 'justify'] -}; - -var AlignAttribute = new _parchment2.default.Attributor.Attribute('align', 'align', config); -var AlignClass = new _parchment2.default.Attributor.Class('align', 'ql-align', config); -var AlignStyle = new _parchment2.default.Attributor.Style('align', 'text-align', config); - -exports.AlignAttribute = AlignAttribute; -exports.AlignClass = AlignClass; -exports.AlignStyle = AlignStyle; - -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.BackgroundStyle = exports.BackgroundClass = undefined; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _color = __webpack_require__(26); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var BackgroundClass = new _parchment2.default.Attributor.Class('background', 'ql-bg', { - scope: _parchment2.default.Scope.INLINE -}); -var BackgroundStyle = new _color.ColorAttributor('background', 'background-color', { - scope: _parchment2.default.Scope.INLINE -}); - -exports.BackgroundClass = BackgroundClass; -exports.BackgroundStyle = BackgroundStyle; - -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.DirectionStyle = exports.DirectionClass = exports.DirectionAttribute = undefined; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var config = { - scope: _parchment2.default.Scope.BLOCK, - whitelist: ['rtl'] -}; - -var DirectionAttribute = new _parchment2.default.Attributor.Attribute('direction', 'dir', config); -var DirectionClass = new _parchment2.default.Attributor.Class('direction', 'ql-direction', config); -var DirectionStyle = new _parchment2.default.Attributor.Style('direction', 'direction', config); - -exports.DirectionAttribute = DirectionAttribute; -exports.DirectionClass = DirectionClass; -exports.DirectionStyle = DirectionStyle; - -/***/ }), -/* 39 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.FontClass = exports.FontStyle = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var config = { - scope: _parchment2.default.Scope.INLINE, - whitelist: ['serif', 'monospace'] -}; - -var FontClass = new _parchment2.default.Attributor.Class('font', 'ql-font', config); - -var FontStyleAttributor = function (_Parchment$Attributor) { - _inherits(FontStyleAttributor, _Parchment$Attributor); - - function FontStyleAttributor() { - _classCallCheck(this, FontStyleAttributor); - - return _possibleConstructorReturn(this, (FontStyleAttributor.__proto__ || Object.getPrototypeOf(FontStyleAttributor)).apply(this, arguments)); - } - - _createClass(FontStyleAttributor, [{ - key: 'value', - value: function value(node) { - return _get(FontStyleAttributor.prototype.__proto__ || Object.getPrototypeOf(FontStyleAttributor.prototype), 'value', this).call(this, node).replace(/["']/g, ''); - } - }]); - - return FontStyleAttributor; -}(_parchment2.default.Attributor.Style); - -var FontStyle = new FontStyleAttributor('font', 'font-family', config); - -exports.FontStyle = FontStyle; -exports.FontClass = FontClass; - -/***/ }), -/* 40 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.SizeStyle = exports.SizeClass = undefined; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var SizeClass = new _parchment2.default.Attributor.Class('size', 'ql-size', { - scope: _parchment2.default.Scope.INLINE, - whitelist: ['small', 'large', 'huge'] -}); -var SizeStyle = new _parchment2.default.Attributor.Style('size', 'font-size', { - scope: _parchment2.default.Scope.INLINE, - whitelist: ['10px', '18px', '32px'] -}); - -exports.SizeClass = SizeClass; -exports.SizeStyle = SizeStyle; - -/***/ }), -/* 41 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - 'align': { - '': __webpack_require__(76), - 'center': __webpack_require__(77), - 'right': __webpack_require__(78), - 'justify': __webpack_require__(79) - }, - 'background': __webpack_require__(80), - 'blockquote': __webpack_require__(81), - 'bold': __webpack_require__(82), - 'clean': __webpack_require__(83), - 'code': __webpack_require__(58), - 'code-block': __webpack_require__(58), - 'color': __webpack_require__(84), - 'direction': { - '': __webpack_require__(85), - 'rtl': __webpack_require__(86) - }, - 'float': { - 'center': __webpack_require__(87), - 'full': __webpack_require__(88), - 'left': __webpack_require__(89), - 'right': __webpack_require__(90) - }, - 'formula': __webpack_require__(91), - 'header': { - '1': __webpack_require__(92), - '2': __webpack_require__(93) - }, - 'italic': __webpack_require__(94), - 'image': __webpack_require__(95), - 'indent': { - '+1': __webpack_require__(96), - '-1': __webpack_require__(97) - }, - 'link': __webpack_require__(98), - 'list': { - 'ordered': __webpack_require__(99), - 'bullet': __webpack_require__(100), - 'check': __webpack_require__(101) - }, - 'script': { - 'sub': __webpack_require__(102), - 'super': __webpack_require__(103) - }, - 'strike': __webpack_require__(104), - 'underline': __webpack_require__(105), - 'video': __webpack_require__(106) -}; - -/***/ }), -/* 42 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getLastChangeIndex = exports.default = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _quill = __webpack_require__(5); - -var _quill2 = _interopRequireDefault(_quill); - -var _module = __webpack_require__(9); - -var _module2 = _interopRequireDefault(_module); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var History = function (_Module) { - _inherits(History, _Module); - - function History(quill, options) { - _classCallCheck(this, History); - - var _this = _possibleConstructorReturn(this, (History.__proto__ || Object.getPrototypeOf(History)).call(this, quill, options)); - - _this.lastRecorded = 0; - _this.ignoreChange = false; - _this.clear(); - _this.quill.on(_quill2.default.events.EDITOR_CHANGE, function (eventName, delta, oldDelta, source) { - if (eventName !== _quill2.default.events.TEXT_CHANGE || _this.ignoreChange) return; - if (!_this.options.userOnly || source === _quill2.default.sources.USER) { - _this.record(delta, oldDelta); - } else { - _this.transform(delta); - } - }); - _this.quill.keyboard.addBinding({ key: 'Z', shortKey: true }, _this.undo.bind(_this)); - _this.quill.keyboard.addBinding({ key: 'Z', shortKey: true, shiftKey: true }, _this.redo.bind(_this)); - if (/Win/i.test(navigator.platform)) { - _this.quill.keyboard.addBinding({ key: 'Y', shortKey: true }, _this.redo.bind(_this)); - } - return _this; - } - - _createClass(History, [{ - key: 'change', - value: function change(source, dest) { - if (this.stack[source].length === 0) return; - var delta = this.stack[source].pop(); - this.stack[dest].push(delta); - this.lastRecorded = 0; - this.ignoreChange = true; - this.quill.updateContents(delta[source], _quill2.default.sources.USER); - this.ignoreChange = false; - var index = getLastChangeIndex(delta[source]); - this.quill.setSelection(index); - } - }, { - key: 'clear', - value: function clear() { - this.stack = { undo: [], redo: [] }; - } - }, { - key: 'cutoff', - value: function cutoff() { - this.lastRecorded = 0; - } - }, { - key: 'record', - value: function record(changeDelta, oldDelta) { - if (changeDelta.ops.length === 0) return; - this.stack.redo = []; - var undoDelta = this.quill.getContents().diff(oldDelta); - var timestamp = Date.now(); - if (this.lastRecorded + this.options.delay > timestamp && this.stack.undo.length > 0) { - var delta = this.stack.undo.pop(); - undoDelta = undoDelta.compose(delta.undo); - changeDelta = delta.redo.compose(changeDelta); - } else { - this.lastRecorded = timestamp; - } - this.stack.undo.push({ - redo: changeDelta, - undo: undoDelta - }); - if (this.stack.undo.length > this.options.maxStack) { - this.stack.undo.shift(); - } - } - }, { - key: 'redo', - value: function redo() { - this.change('redo', 'undo'); - } - }, { - key: 'transform', - value: function transform(delta) { - this.stack.undo.forEach(function (change) { - change.undo = delta.transform(change.undo, true); - change.redo = delta.transform(change.redo, true); - }); - this.stack.redo.forEach(function (change) { - change.undo = delta.transform(change.undo, true); - change.redo = delta.transform(change.redo, true); - }); - } - }, { - key: 'undo', - value: function undo() { - this.change('undo', 'redo'); - } - }]); - - return History; -}(_module2.default); - -History.DEFAULTS = { - delay: 1000, - maxStack: 100, - userOnly: false -}; - -function endsWithNewlineChange(delta) { - var lastOp = delta.ops[delta.ops.length - 1]; - if (lastOp == null) return false; - if (lastOp.insert != null) { - return typeof lastOp.insert === 'string' && lastOp.insert.endsWith('\n'); - } - if (lastOp.attributes != null) { - return Object.keys(lastOp.attributes).some(function (attr) { - return _parchment2.default.query(attr, _parchment2.default.Scope.BLOCK) != null; - }); - } - return false; -} - -function getLastChangeIndex(delta) { - var deleteLength = delta.reduce(function (length, op) { - length += op.delete || 0; - return length; - }, 0); - var changeIndex = delta.length() - deleteLength; - if (endsWithNewlineChange(delta)) { - changeIndex -= 1; - } - return changeIndex; -} - -exports.default = History; -exports.getLastChangeIndex = getLastChangeIndex; - -/***/ }), -/* 43 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.BaseTooltip = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _extend = __webpack_require__(3); - -var _extend2 = _interopRequireDefault(_extend); - -var _quillDelta = __webpack_require__(2); - -var _quillDelta2 = _interopRequireDefault(_quillDelta); - -var _emitter = __webpack_require__(8); - -var _emitter2 = _interopRequireDefault(_emitter); - -var _keyboard = __webpack_require__(23); - -var _keyboard2 = _interopRequireDefault(_keyboard); - -var _theme = __webpack_require__(34); - -var _theme2 = _interopRequireDefault(_theme); - -var _colorPicker = __webpack_require__(59); - -var _colorPicker2 = _interopRequireDefault(_colorPicker); - -var _iconPicker = __webpack_require__(60); - -var _iconPicker2 = _interopRequireDefault(_iconPicker); - -var _picker = __webpack_require__(28); - -var _picker2 = _interopRequireDefault(_picker); - -var _tooltip = __webpack_require__(61); - -var _tooltip2 = _interopRequireDefault(_tooltip); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var ALIGNS = [false, 'center', 'right', 'justify']; - -var COLORS = ["#000000", "#e60000", "#ff9900", "#ffff00", "#008a00", "#0066cc", "#9933ff", "#ffffff", "#facccc", "#ffebcc", "#ffffcc", "#cce8cc", "#cce0f5", "#ebd6ff", "#bbbbbb", "#f06666", "#ffc266", "#ffff66", "#66b966", "#66a3e0", "#c285ff", "#888888", "#a10000", "#b26b00", "#b2b200", "#006100", "#0047b2", "#6b24b2", "#444444", "#5c0000", "#663d00", "#666600", "#003700", "#002966", "#3d1466"]; - -var FONTS = [false, 'serif', 'monospace']; - -var HEADERS = ['1', '2', '3', false]; - -var SIZES = ['small', false, 'large', 'huge']; - -var BaseTheme = function (_Theme) { - _inherits(BaseTheme, _Theme); - - function BaseTheme(quill, options) { - _classCallCheck(this, BaseTheme); - - var _this = _possibleConstructorReturn(this, (BaseTheme.__proto__ || Object.getPrototypeOf(BaseTheme)).call(this, quill, options)); - - var listener = function listener(e) { - if (!document.body.contains(quill.root)) { - return document.body.removeEventListener('click', listener); - } - if (_this.tooltip != null && !_this.tooltip.root.contains(e.target) && document.activeElement !== _this.tooltip.textbox && !_this.quill.hasFocus()) { - _this.tooltip.hide(); - } - if (_this.pickers != null) { - _this.pickers.forEach(function (picker) { - if (!picker.container.contains(e.target)) { - picker.close(); - } - }); - } - }; - quill.emitter.listenDOM('click', document.body, listener); - return _this; - } - - _createClass(BaseTheme, [{ - key: 'addModule', - value: function addModule(name) { - var module = _get(BaseTheme.prototype.__proto__ || Object.getPrototypeOf(BaseTheme.prototype), 'addModule', this).call(this, name); - if (name === 'toolbar') { - this.extendToolbar(module); - } - return module; - } - }, { - key: 'buildButtons', - value: function buildButtons(buttons, icons) { - buttons.forEach(function (button) { - var className = button.getAttribute('class') || ''; - className.split(/\s+/).forEach(function (name) { - if (!name.startsWith('ql-')) return; - name = name.slice('ql-'.length); - if (icons[name] == null) return; - if (name === 'direction') { - button.innerHTML = icons[name][''] + icons[name]['rtl']; - } else if (typeof icons[name] === 'string') { - button.innerHTML = icons[name]; - } else { - var value = button.value || ''; - if (value != null && icons[name][value]) { - button.innerHTML = icons[name][value]; - } - } - }); - }); - } - }, { - key: 'buildPickers', - value: function buildPickers(selects, icons) { - var _this2 = this; - - this.pickers = selects.map(function (select) { - if (select.classList.contains('ql-align')) { - if (select.querySelector('option') == null) { - fillSelect(select, ALIGNS); - } - return new _iconPicker2.default(select, icons.align); - } else if (select.classList.contains('ql-background') || select.classList.contains('ql-color')) { - var format = select.classList.contains('ql-background') ? 'background' : 'color'; - if (select.querySelector('option') == null) { - fillSelect(select, COLORS, format === 'background' ? '#ffffff' : '#000000'); - } - return new _colorPicker2.default(select, icons[format]); - } else { - if (select.querySelector('option') == null) { - if (select.classList.contains('ql-font')) { - fillSelect(select, FONTS); - } else if (select.classList.contains('ql-header')) { - fillSelect(select, HEADERS); - } else if (select.classList.contains('ql-size')) { - fillSelect(select, SIZES); - } - } - return new _picker2.default(select); - } - }); - var update = function update() { - _this2.pickers.forEach(function (picker) { - picker.update(); - }); - }; - this.quill.on(_emitter2.default.events.EDITOR_CHANGE, update); - } - }]); - - return BaseTheme; -}(_theme2.default); - -BaseTheme.DEFAULTS = (0, _extend2.default)(true, {}, _theme2.default.DEFAULTS, { - modules: { - toolbar: { - handlers: { - formula: function formula() { - this.quill.theme.tooltip.edit('formula'); - }, - image: function image() { - var _this3 = this; - - var fileInput = this.container.querySelector('input.ql-image[type=file]'); - if (fileInput == null) { - fileInput = document.createElement('input'); - fileInput.setAttribute('type', 'file'); - fileInput.setAttribute('accept', 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon'); - fileInput.classList.add('ql-image'); - fileInput.addEventListener('change', function () { - if (fileInput.files != null && fileInput.files[0] != null) { - var reader = new FileReader(); - reader.onload = function (e) { - var range = _this3.quill.getSelection(true); - _this3.quill.updateContents(new _quillDelta2.default().retain(range.index).delete(range.length).insert({ image: e.target.result }), _emitter2.default.sources.USER); - _this3.quill.setSelection(range.index + 1, _emitter2.default.sources.SILENT); - fileInput.value = ""; - }; - reader.readAsDataURL(fileInput.files[0]); - } - }); - this.container.appendChild(fileInput); - } - fileInput.click(); - }, - video: function video() { - this.quill.theme.tooltip.edit('video'); - } - } - } - } -}); - -var BaseTooltip = function (_Tooltip) { - _inherits(BaseTooltip, _Tooltip); - - function BaseTooltip(quill, boundsContainer) { - _classCallCheck(this, BaseTooltip); - - var _this4 = _possibleConstructorReturn(this, (BaseTooltip.__proto__ || Object.getPrototypeOf(BaseTooltip)).call(this, quill, boundsContainer)); - - _this4.textbox = _this4.root.querySelector('input[type="text"]'); - _this4.listen(); - return _this4; - } - - _createClass(BaseTooltip, [{ - key: 'listen', - value: function listen() { - var _this5 = this; - - this.textbox.addEventListener('keydown', function (event) { - if (_keyboard2.default.match(event, 'enter')) { - _this5.save(); - event.preventDefault(); - } else if (_keyboard2.default.match(event, 'escape')) { - _this5.cancel(); - event.preventDefault(); - } - }); - } - }, { - key: 'cancel', - value: function cancel() { - this.hide(); - } - }, { - key: 'edit', - value: function edit() { - var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'link'; - var preview = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - - this.root.classList.remove('ql-hidden'); - this.root.classList.add('ql-editing'); - if (preview != null) { - this.textbox.value = preview; - } else if (mode !== this.root.getAttribute('data-mode')) { - this.textbox.value = ''; - } - this.position(this.quill.getBounds(this.quill.selection.savedRange)); - this.textbox.select(); - this.textbox.setAttribute('placeholder', this.textbox.getAttribute('data-' + mode) || ''); - this.root.setAttribute('data-mode', mode); - } - }, { - key: 'restoreFocus', - value: function restoreFocus() { - var scrollTop = this.quill.scrollingContainer.scrollTop; - this.quill.focus(); - this.quill.scrollingContainer.scrollTop = scrollTop; - } - }, { - key: 'save', - value: function save() { - var value = this.textbox.value; - switch (this.root.getAttribute('data-mode')) { - case 'link': - { - var scrollTop = this.quill.root.scrollTop; - if (this.linkRange) { - this.quill.formatText(this.linkRange, 'link', value, _emitter2.default.sources.USER); - delete this.linkRange; - } else { - this.restoreFocus(); - this.quill.format('link', value, _emitter2.default.sources.USER); - } - this.quill.root.scrollTop = scrollTop; - break; - } - case 'video': - { - value = extractVideoUrl(value); - } // eslint-disable-next-line no-fallthrough - case 'formula': - { - if (!value) break; - var range = this.quill.getSelection(true); - if (range != null) { - var index = range.index + range.length; - this.quill.insertEmbed(index, this.root.getAttribute('data-mode'), value, _emitter2.default.sources.USER); - if (this.root.getAttribute('data-mode') === 'formula') { - this.quill.insertText(index + 1, ' ', _emitter2.default.sources.USER); - } - this.quill.setSelection(index + 2, _emitter2.default.sources.USER); - } - break; - } - default: - } - this.textbox.value = ''; - this.hide(); - } - }]); - - return BaseTooltip; -}(_tooltip2.default); - -function extractVideoUrl(url) { - var match = url.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtube\.com\/watch.*v=([a-zA-Z0-9_-]+)/) || url.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtu\.be\/([a-zA-Z0-9_-]+)/); - if (match) { - return (match[1] || 'https') + '://www.youtube.com/embed/' + match[2] + '?showinfo=0'; - } - if (match = url.match(/^(?:(https?):\/\/)?(?:www\.)?vimeo\.com\/(\d+)/)) { - // eslint-disable-line no-cond-assign - return (match[1] || 'https') + '://player.vimeo.com/video/' + match[2] + '/'; - } - return url; -} - -function fillSelect(select, values) { - var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - values.forEach(function (value) { - var option = document.createElement('option'); - if (value === defaultValue) { - option.setAttribute('selected', 'selected'); - } else { - option.setAttribute('value', value); - } - select.appendChild(option); - }); -} - -exports.BaseTooltip = BaseTooltip; -exports.default = BaseTheme; - -/***/ }), -/* 44 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var LinkedList = /** @class */ (function () { - function LinkedList() { - this.head = this.tail = null; - this.length = 0; - } - LinkedList.prototype.append = function () { - var nodes = []; - for (var _i = 0; _i < arguments.length; _i++) { - nodes[_i] = arguments[_i]; - } - this.insertBefore(nodes[0], null); - if (nodes.length > 1) { - this.append.apply(this, nodes.slice(1)); - } - }; - LinkedList.prototype.contains = function (node) { - var cur, next = this.iterator(); - while ((cur = next())) { - if (cur === node) - return true; - } - return false; - }; - LinkedList.prototype.insertBefore = function (node, refNode) { - if (!node) - return; - node.next = refNode; - if (refNode != null) { - node.prev = refNode.prev; - if (refNode.prev != null) { - refNode.prev.next = node; - } - refNode.prev = node; - if (refNode === this.head) { - this.head = node; - } - } - else if (this.tail != null) { - this.tail.next = node; - node.prev = this.tail; - this.tail = node; - } - else { - node.prev = null; - this.head = this.tail = node; - } - this.length += 1; - }; - LinkedList.prototype.offset = function (target) { - var index = 0, cur = this.head; - while (cur != null) { - if (cur === target) - return index; - index += cur.length(); - cur = cur.next; - } - return -1; - }; - LinkedList.prototype.remove = function (node) { - if (!this.contains(node)) - return; - if (node.prev != null) - node.prev.next = node.next; - if (node.next != null) - node.next.prev = node.prev; - if (node === this.head) - this.head = node.next; - if (node === this.tail) - this.tail = node.prev; - this.length -= 1; - }; - LinkedList.prototype.iterator = function (curNode) { - if (curNode === void 0) { curNode = this.head; } - // TODO use yield when we can - return function () { - var ret = curNode; - if (curNode != null) - curNode = curNode.next; - return ret; - }; - }; - LinkedList.prototype.find = function (index, inclusive) { - if (inclusive === void 0) { inclusive = false; } - var cur, next = this.iterator(); - while ((cur = next())) { - var length = cur.length(); - if (index < length || - (inclusive && index === length && (cur.next == null || cur.next.length() !== 0))) { - return [cur, index]; - } - index -= length; - } - return [null, 0]; - }; - LinkedList.prototype.forEach = function (callback) { - var cur, next = this.iterator(); - while ((cur = next())) { - callback(cur); - } - }; - LinkedList.prototype.forEachAt = function (index, length, callback) { - if (length <= 0) - return; - var _a = this.find(index), startNode = _a[0], offset = _a[1]; - var cur, curIndex = index - offset, next = this.iterator(startNode); - while ((cur = next()) && curIndex < index + length) { - var curLength = cur.length(); - if (index > curIndex) { - callback(cur, index - curIndex, Math.min(length, curIndex + curLength - index)); - } - else { - callback(cur, 0, Math.min(curLength, index + length - curIndex)); - } - curIndex += curLength; - } - }; - LinkedList.prototype.map = function (callback) { - return this.reduce(function (memo, cur) { - memo.push(callback(cur)); - return memo; - }, []); - }; - LinkedList.prototype.reduce = function (callback, memo) { - var cur, next = this.iterator(); - while ((cur = next())) { - memo = callback(memo, cur); - } - return memo; - }; - return LinkedList; -}()); -exports.default = LinkedList; - - -/***/ }), -/* 45 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(17); -var Registry = __webpack_require__(1); -var OBSERVER_CONFIG = { - attributes: true, - characterData: true, - characterDataOldValue: true, - childList: true, - subtree: true, -}; -var MAX_OPTIMIZE_ITERATIONS = 100; -var ScrollBlot = /** @class */ (function (_super) { - __extends(ScrollBlot, _super); - function ScrollBlot(node) { - var _this = _super.call(this, node) || this; - _this.scroll = _this; - _this.observer = new MutationObserver(function (mutations) { - _this.update(mutations); - }); - _this.observer.observe(_this.domNode, OBSERVER_CONFIG); - _this.attach(); - return _this; - } - ScrollBlot.prototype.detach = function () { - _super.prototype.detach.call(this); - this.observer.disconnect(); - }; - ScrollBlot.prototype.deleteAt = function (index, length) { - this.update(); - if (index === 0 && length === this.length()) { - this.children.forEach(function (child) { - child.remove(); - }); - } - else { - _super.prototype.deleteAt.call(this, index, length); - } - }; - ScrollBlot.prototype.formatAt = function (index, length, name, value) { - this.update(); - _super.prototype.formatAt.call(this, index, length, name, value); - }; - ScrollBlot.prototype.insertAt = function (index, value, def) { - this.update(); - _super.prototype.insertAt.call(this, index, value, def); - }; - ScrollBlot.prototype.optimize = function (mutations, context) { - var _this = this; - if (mutations === void 0) { mutations = []; } - if (context === void 0) { context = {}; } - _super.prototype.optimize.call(this, context); - // We must modify mutations directly, cannot make copy and then modify - var records = [].slice.call(this.observer.takeRecords()); - // Array.push currently seems to be implemented by a non-tail recursive function - // so we cannot just mutations.push.apply(mutations, this.observer.takeRecords()); - while (records.length > 0) - mutations.push(records.pop()); - // TODO use WeakMap - var mark = function (blot, markParent) { - if (markParent === void 0) { markParent = true; } - if (blot == null || blot === _this) - return; - if (blot.domNode.parentNode == null) - return; - // @ts-ignore - if (blot.domNode[Registry.DATA_KEY].mutations == null) { - // @ts-ignore - blot.domNode[Registry.DATA_KEY].mutations = []; - } - if (markParent) - mark(blot.parent); - }; - var optimize = function (blot) { - // Post-order traversal - if ( - // @ts-ignore - blot.domNode[Registry.DATA_KEY] == null || - // @ts-ignore - blot.domNode[Registry.DATA_KEY].mutations == null) { - return; - } - if (blot instanceof container_1.default) { - blot.children.forEach(optimize); - } - blot.optimize(context); - }; - var remaining = mutations; - for (var i = 0; remaining.length > 0; i += 1) { - if (i >= MAX_OPTIMIZE_ITERATIONS) { - throw new Error('[Parchment] Maximum optimize iterations reached'); - } - remaining.forEach(function (mutation) { - var blot = Registry.find(mutation.target, true); - if (blot == null) - return; - if (blot.domNode === mutation.target) { - if (mutation.type === 'childList') { - mark(Registry.find(mutation.previousSibling, false)); - [].forEach.call(mutation.addedNodes, function (node) { - var child = Registry.find(node, false); - mark(child, false); - if (child instanceof container_1.default) { - child.children.forEach(function (grandChild) { - mark(grandChild, false); - }); - } - }); - } - else if (mutation.type === 'attributes') { - mark(blot.prev); - } - } - mark(blot); - }); - this.children.forEach(optimize); - remaining = [].slice.call(this.observer.takeRecords()); - records = remaining.slice(); - while (records.length > 0) - mutations.push(records.pop()); - } - }; - ScrollBlot.prototype.update = function (mutations, context) { - var _this = this; - if (context === void 0) { context = {}; } - mutations = mutations || this.observer.takeRecords(); - // TODO use WeakMap - mutations - .map(function (mutation) { - var blot = Registry.find(mutation.target, true); - if (blot == null) - return null; - // @ts-ignore - if (blot.domNode[Registry.DATA_KEY].mutations == null) { - // @ts-ignore - blot.domNode[Registry.DATA_KEY].mutations = [mutation]; - return blot; - } - else { - // @ts-ignore - blot.domNode[Registry.DATA_KEY].mutations.push(mutation); - return null; - } - }) - .forEach(function (blot) { - if (blot == null || - blot === _this || - //@ts-ignore - blot.domNode[Registry.DATA_KEY] == null) - return; - // @ts-ignore - blot.update(blot.domNode[Registry.DATA_KEY].mutations || [], context); - }); - // @ts-ignore - if (this.domNode[Registry.DATA_KEY].mutations != null) { - // @ts-ignore - _super.prototype.update.call(this, this.domNode[Registry.DATA_KEY].mutations, context); - } - this.optimize(mutations, context); - }; - ScrollBlot.blotName = 'scroll'; - ScrollBlot.defaultChild = 'block'; - ScrollBlot.scope = Registry.Scope.BLOCK_BLOT; - ScrollBlot.tagName = 'DIV'; - return ScrollBlot; -}(container_1.default)); -exports.default = ScrollBlot; - - -/***/ }), -/* 46 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var format_1 = __webpack_require__(18); -var Registry = __webpack_require__(1); -// Shallow object comparison -function isEqual(obj1, obj2) { - if (Object.keys(obj1).length !== Object.keys(obj2).length) - return false; - // @ts-ignore - for (var prop in obj1) { - // @ts-ignore - if (obj1[prop] !== obj2[prop]) - return false; - } - return true; -} -var InlineBlot = /** @class */ (function (_super) { - __extends(InlineBlot, _super); - function InlineBlot() { - return _super !== null && _super.apply(this, arguments) || this; - } - InlineBlot.formats = function (domNode) { - if (domNode.tagName === InlineBlot.tagName) - return undefined; - return _super.formats.call(this, domNode); - }; - InlineBlot.prototype.format = function (name, value) { - var _this = this; - if (name === this.statics.blotName && !value) { - this.children.forEach(function (child) { - if (!(child instanceof format_1.default)) { - child = child.wrap(InlineBlot.blotName, true); - } - _this.attributes.copy(child); - }); - this.unwrap(); - } - else { - _super.prototype.format.call(this, name, value); - } - }; - InlineBlot.prototype.formatAt = function (index, length, name, value) { - if (this.formats()[name] != null || Registry.query(name, Registry.Scope.ATTRIBUTE)) { - var blot = this.isolate(index, length); - blot.format(name, value); - } - else { - _super.prototype.formatAt.call(this, index, length, name, value); - } - }; - InlineBlot.prototype.optimize = function (context) { - _super.prototype.optimize.call(this, context); - var formats = this.formats(); - if (Object.keys(formats).length === 0) { - return this.unwrap(); // unformatted span - } - var next = this.next; - if (next instanceof InlineBlot && next.prev === this && isEqual(formats, next.formats())) { - next.moveChildren(this); - next.remove(); - } - }; - InlineBlot.blotName = 'inline'; - InlineBlot.scope = Registry.Scope.INLINE_BLOT; - InlineBlot.tagName = 'SPAN'; - return InlineBlot; -}(format_1.default)); -exports.default = InlineBlot; - - -/***/ }), -/* 47 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var format_1 = __webpack_require__(18); -var Registry = __webpack_require__(1); -var BlockBlot = /** @class */ (function (_super) { - __extends(BlockBlot, _super); - function BlockBlot() { - return _super !== null && _super.apply(this, arguments) || this; - } - BlockBlot.formats = function (domNode) { - var tagName = Registry.query(BlockBlot.blotName).tagName; - if (domNode.tagName === tagName) - return undefined; - return _super.formats.call(this, domNode); - }; - BlockBlot.prototype.format = function (name, value) { - if (Registry.query(name, Registry.Scope.BLOCK) == null) { - return; - } - else if (name === this.statics.blotName && !value) { - this.replaceWith(BlockBlot.blotName); - } - else { - _super.prototype.format.call(this, name, value); - } - }; - BlockBlot.prototype.formatAt = function (index, length, name, value) { - if (Registry.query(name, Registry.Scope.BLOCK) != null) { - this.format(name, value); - } - else { - _super.prototype.formatAt.call(this, index, length, name, value); - } - }; - BlockBlot.prototype.insertAt = function (index, value, def) { - if (def == null || Registry.query(value, Registry.Scope.INLINE) != null) { - // Insert text or inline - _super.prototype.insertAt.call(this, index, value, def); - } - else { - var after = this.split(index); - var blot = Registry.create(value, def); - after.parent.insertBefore(blot, after); - } - }; - BlockBlot.prototype.update = function (mutations, context) { - if (navigator.userAgent.match(/Trident/)) { - this.build(); - } - else { - _super.prototype.update.call(this, mutations, context); - } - }; - BlockBlot.blotName = 'block'; - BlockBlot.scope = Registry.Scope.BLOCK_BLOT; - BlockBlot.tagName = 'P'; - return BlockBlot; -}(format_1.default)); -exports.default = BlockBlot; - - -/***/ }), -/* 48 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var leaf_1 = __webpack_require__(19); -var EmbedBlot = /** @class */ (function (_super) { - __extends(EmbedBlot, _super); - function EmbedBlot() { - return _super !== null && _super.apply(this, arguments) || this; - } - EmbedBlot.formats = function (domNode) { - return undefined; - }; - EmbedBlot.prototype.format = function (name, value) { - // super.formatAt wraps, which is what we want in general, - // but this allows subclasses to overwrite for formats - // that just apply to particular embeds - _super.prototype.formatAt.call(this, 0, this.length(), name, value); - }; - EmbedBlot.prototype.formatAt = function (index, length, name, value) { - if (index === 0 && length === this.length()) { - this.format(name, value); - } - else { - _super.prototype.formatAt.call(this, index, length, name, value); - } - }; - EmbedBlot.prototype.formats = function () { - return this.statics.formats(this.domNode); - }; - return EmbedBlot; -}(leaf_1.default)); -exports.default = EmbedBlot; - - -/***/ }), -/* 49 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var leaf_1 = __webpack_require__(19); -var Registry = __webpack_require__(1); -var TextBlot = /** @class */ (function (_super) { - __extends(TextBlot, _super); - function TextBlot(node) { - var _this = _super.call(this, node) || this; - _this.text = _this.statics.value(_this.domNode); - return _this; - } - TextBlot.create = function (value) { - return document.createTextNode(value); - }; - TextBlot.value = function (domNode) { - var text = domNode.data; - // @ts-ignore - if (text['normalize']) - text = text['normalize'](); - return text; - }; - TextBlot.prototype.deleteAt = function (index, length) { - this.domNode.data = this.text = this.text.slice(0, index) + this.text.slice(index + length); - }; - TextBlot.prototype.index = function (node, offset) { - if (this.domNode === node) { - return offset; - } - return -1; - }; - TextBlot.prototype.insertAt = function (index, value, def) { - if (def == null) { - this.text = this.text.slice(0, index) + value + this.text.slice(index); - this.domNode.data = this.text; - } - else { - _super.prototype.insertAt.call(this, index, value, def); - } - }; - TextBlot.prototype.length = function () { - return this.text.length; - }; - TextBlot.prototype.optimize = function (context) { - _super.prototype.optimize.call(this, context); - this.text = this.statics.value(this.domNode); - if (this.text.length === 0) { - this.remove(); - } - else if (this.next instanceof TextBlot && this.next.prev === this) { - this.insertAt(this.length(), this.next.value()); - this.next.remove(); - } - }; - TextBlot.prototype.position = function (index, inclusive) { - if (inclusive === void 0) { inclusive = false; } - return [this.domNode, index]; - }; - TextBlot.prototype.split = function (index, force) { - if (force === void 0) { force = false; } - if (!force) { - if (index === 0) - return this; - if (index === this.length()) - return this.next; - } - var after = Registry.create(this.domNode.splitText(index)); - this.parent.insertBefore(after, this.next); - this.text = this.statics.value(this.domNode); - return after; - }; - TextBlot.prototype.update = function (mutations, context) { - var _this = this; - if (mutations.some(function (mutation) { - return mutation.type === 'characterData' && mutation.target === _this.domNode; - })) { - this.text = this.statics.value(this.domNode); - } - }; - TextBlot.prototype.value = function () { - return this.text; - }; - TextBlot.blotName = 'text'; - TextBlot.scope = Registry.Scope.INLINE_BLOT; - return TextBlot; -}(leaf_1.default)); -exports.default = TextBlot; - - -/***/ }), -/* 50 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var elem = document.createElement('div'); -elem.classList.toggle('test-class', false); -if (elem.classList.contains('test-class')) { - var _toggle = DOMTokenList.prototype.toggle; - DOMTokenList.prototype.toggle = function (token, force) { - if (arguments.length > 1 && !this.contains(token) === !force) { - return force; - } else { - return _toggle.call(this, token); - } - }; -} - -if (!String.prototype.startsWith) { - String.prototype.startsWith = function (searchString, position) { - position = position || 0; - return this.substr(position, searchString.length) === searchString; - }; -} - -if (!String.prototype.endsWith) { - String.prototype.endsWith = function (searchString, position) { - var subjectString = this.toString(); - if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { - position = subjectString.length; - } - position -= searchString.length; - var lastIndex = subjectString.indexOf(searchString, position); - return lastIndex !== -1 && lastIndex === position; - }; -} - -if (!Array.prototype.find) { - Object.defineProperty(Array.prototype, "find", { - value: function value(predicate) { - if (this === null) { - throw new TypeError('Array.prototype.find called on null or undefined'); - } - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function'); - } - var list = Object(this); - var length = list.length >>> 0; - var thisArg = arguments[1]; - var value; - - for (var i = 0; i < length; i++) { - value = list[i]; - if (predicate.call(thisArg, value, i, list)) { - return value; - } - } - return undefined; - } - }); -} - -document.addEventListener("DOMContentLoaded", function () { - // Disable resizing in Firefox - document.execCommand("enableObjectResizing", false, false); - // Disable automatic linkifying in IE11 - document.execCommand("autoUrlDetect", false, false); -}); - -/***/ }), -/* 51 */ -/***/ (function(module, exports) { - -/** - * This library modifies the diff-patch-match library by Neil Fraser - * by removing the patch and match functionality and certain advanced - * options in the diff function. The original license is as follows: - * - * === - * - * Diff Match and Patch - * - * Copyright 2006 Google Inc. - * http://code.google.com/p/google-diff-match-patch/ - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -/** - * The data structure representing a diff is an array of tuples: - * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']] - * which means: delete 'Hello', add 'Goodbye' and keep ' world.' - */ -var DIFF_DELETE = -1; -var DIFF_INSERT = 1; -var DIFF_EQUAL = 0; - - -/** - * Find the differences between two texts. Simplifies the problem by stripping - * any common prefix or suffix off the texts before diffing. - * @param {string} text1 Old string to be diffed. - * @param {string} text2 New string to be diffed. - * @param {Int} cursor_pos Expected edit position in text1 (optional) - * @return {Array} Array of diff tuples. - */ -function diff_main(text1, text2, cursor_pos) { - // Check for equality (speedup). - if (text1 == text2) { - if (text1) { - return [[DIFF_EQUAL, text1]]; - } - return []; - } - - // Check cursor_pos within bounds - if (cursor_pos < 0 || text1.length < cursor_pos) { - cursor_pos = null; - } - - // Trim off common prefix (speedup). - var commonlength = diff_commonPrefix(text1, text2); - var commonprefix = text1.substring(0, commonlength); - text1 = text1.substring(commonlength); - text2 = text2.substring(commonlength); - - // Trim off common suffix (speedup). - commonlength = diff_commonSuffix(text1, text2); - var commonsuffix = text1.substring(text1.length - commonlength); - text1 = text1.substring(0, text1.length - commonlength); - text2 = text2.substring(0, text2.length - commonlength); - - // Compute the diff on the middle block. - var diffs = diff_compute_(text1, text2); - - // Restore the prefix and suffix. - if (commonprefix) { - diffs.unshift([DIFF_EQUAL, commonprefix]); - } - if (commonsuffix) { - diffs.push([DIFF_EQUAL, commonsuffix]); - } - diff_cleanupMerge(diffs); - if (cursor_pos != null) { - diffs = fix_cursor(diffs, cursor_pos); - } - diffs = fix_emoji(diffs); - return diffs; -}; - - -/** - * Find the differences between two texts. Assumes that the texts do not - * have any common prefix or suffix. - * @param {string} text1 Old string to be diffed. - * @param {string} text2 New string to be diffed. - * @return {Array} Array of diff tuples. - */ -function diff_compute_(text1, text2) { - var diffs; - - if (!text1) { - // Just add some text (speedup). - return [[DIFF_INSERT, text2]]; - } - - if (!text2) { - // Just delete some text (speedup). - return [[DIFF_DELETE, text1]]; - } - - var longtext = text1.length > text2.length ? text1 : text2; - var shorttext = text1.length > text2.length ? text2 : text1; - var i = longtext.indexOf(shorttext); - if (i != -1) { - // Shorter text is inside the longer text (speedup). - diffs = [[DIFF_INSERT, longtext.substring(0, i)], - [DIFF_EQUAL, shorttext], - [DIFF_INSERT, longtext.substring(i + shorttext.length)]]; - // Swap insertions for deletions if diff is reversed. - if (text1.length > text2.length) { - diffs[0][0] = diffs[2][0] = DIFF_DELETE; - } - return diffs; - } - - if (shorttext.length == 1) { - // Single character string. - // After the previous speedup, the character can't be an equality. - return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]]; - } - - // Check to see if the problem can be split in two. - var hm = diff_halfMatch_(text1, text2); - if (hm) { - // A half-match was found, sort out the return data. - var text1_a = hm[0]; - var text1_b = hm[1]; - var text2_a = hm[2]; - var text2_b = hm[3]; - var mid_common = hm[4]; - // Send both pairs off for separate processing. - var diffs_a = diff_main(text1_a, text2_a); - var diffs_b = diff_main(text1_b, text2_b); - // Merge the results. - return diffs_a.concat([[DIFF_EQUAL, mid_common]], diffs_b); - } - - return diff_bisect_(text1, text2); -}; - - -/** - * Find the 'middle snake' of a diff, split the problem in two - * and return the recursively constructed diff. - * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations. - * @param {string} text1 Old string to be diffed. - * @param {string} text2 New string to be diffed. - * @return {Array} Array of diff tuples. - * @private - */ -function diff_bisect_(text1, text2) { - // Cache the text lengths to prevent multiple calls. - var text1_length = text1.length; - var text2_length = text2.length; - var max_d = Math.ceil((text1_length + text2_length) / 2); - var v_offset = max_d; - var v_length = 2 * max_d; - var v1 = new Array(v_length); - var v2 = new Array(v_length); - // Setting all elements to -1 is faster in Chrome & Firefox than mixing - // integers and undefined. - for (var x = 0; x < v_length; x++) { - v1[x] = -1; - v2[x] = -1; - } - v1[v_offset + 1] = 0; - v2[v_offset + 1] = 0; - var delta = text1_length - text2_length; - // If the total number of characters is odd, then the front path will collide - // with the reverse path. - var front = (delta % 2 != 0); - // Offsets for start and end of k loop. - // Prevents mapping of space beyond the grid. - var k1start = 0; - var k1end = 0; - var k2start = 0; - var k2end = 0; - for (var d = 0; d < max_d; d++) { - // Walk the front path one step. - for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) { - var k1_offset = v_offset + k1; - var x1; - if (k1 == -d || (k1 != d && v1[k1_offset - 1] < v1[k1_offset + 1])) { - x1 = v1[k1_offset + 1]; - } else { - x1 = v1[k1_offset - 1] + 1; - } - var y1 = x1 - k1; - while (x1 < text1_length && y1 < text2_length && - text1.charAt(x1) == text2.charAt(y1)) { - x1++; - y1++; - } - v1[k1_offset] = x1; - if (x1 > text1_length) { - // Ran off the right of the graph. - k1end += 2; - } else if (y1 > text2_length) { - // Ran off the bottom of the graph. - k1start += 2; - } else if (front) { - var k2_offset = v_offset + delta - k1; - if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] != -1) { - // Mirror x2 onto top-left coordinate system. - var x2 = text1_length - v2[k2_offset]; - if (x1 >= x2) { - // Overlap detected. - return diff_bisectSplit_(text1, text2, x1, y1); - } - } - } - } - - // Walk the reverse path one step. - for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) { - var k2_offset = v_offset + k2; - var x2; - if (k2 == -d || (k2 != d && v2[k2_offset - 1] < v2[k2_offset + 1])) { - x2 = v2[k2_offset + 1]; - } else { - x2 = v2[k2_offset - 1] + 1; - } - var y2 = x2 - k2; - while (x2 < text1_length && y2 < text2_length && - text1.charAt(text1_length - x2 - 1) == - text2.charAt(text2_length - y2 - 1)) { - x2++; - y2++; - } - v2[k2_offset] = x2; - if (x2 > text1_length) { - // Ran off the left of the graph. - k2end += 2; - } else if (y2 > text2_length) { - // Ran off the top of the graph. - k2start += 2; - } else if (!front) { - var k1_offset = v_offset + delta - k2; - if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] != -1) { - var x1 = v1[k1_offset]; - var y1 = v_offset + x1 - k1_offset; - // Mirror x2 onto top-left coordinate system. - x2 = text1_length - x2; - if (x1 >= x2) { - // Overlap detected. - return diff_bisectSplit_(text1, text2, x1, y1); - } - } - } - } - } - // Diff took too long and hit the deadline or - // number of diffs equals number of characters, no commonality at all. - return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]]; -}; - - -/** - * Given the location of the 'middle snake', split the diff in two parts - * and recurse. - * @param {string} text1 Old string to be diffed. - * @param {string} text2 New string to be diffed. - * @param {number} x Index of split point in text1. - * @param {number} y Index of split point in text2. - * @return {Array} Array of diff tuples. - */ -function diff_bisectSplit_(text1, text2, x, y) { - var text1a = text1.substring(0, x); - var text2a = text2.substring(0, y); - var text1b = text1.substring(x); - var text2b = text2.substring(y); - - // Compute both diffs serially. - var diffs = diff_main(text1a, text2a); - var diffsb = diff_main(text1b, text2b); - - return diffs.concat(diffsb); -}; - - -/** - * Determine the common prefix of two strings. - * @param {string} text1 First string. - * @param {string} text2 Second string. - * @return {number} The number of characters common to the start of each - * string. - */ -function diff_commonPrefix(text1, text2) { - // Quick check for common null cases. - if (!text1 || !text2 || text1.charAt(0) != text2.charAt(0)) { - return 0; - } - // Binary search. - // Performance analysis: http://neil.fraser.name/news/2007/10/09/ - var pointermin = 0; - var pointermax = Math.min(text1.length, text2.length); - var pointermid = pointermax; - var pointerstart = 0; - while (pointermin < pointermid) { - if (text1.substring(pointerstart, pointermid) == - text2.substring(pointerstart, pointermid)) { - pointermin = pointermid; - pointerstart = pointermin; - } else { - pointermax = pointermid; - } - pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); - } - return pointermid; -}; - - -/** - * Determine the common suffix of two strings. - * @param {string} text1 First string. - * @param {string} text2 Second string. - * @return {number} The number of characters common to the end of each string. - */ -function diff_commonSuffix(text1, text2) { - // Quick check for common null cases. - if (!text1 || !text2 || - text1.charAt(text1.length - 1) != text2.charAt(text2.length - 1)) { - return 0; - } - // Binary search. - // Performance analysis: http://neil.fraser.name/news/2007/10/09/ - var pointermin = 0; - var pointermax = Math.min(text1.length, text2.length); - var pointermid = pointermax; - var pointerend = 0; - while (pointermin < pointermid) { - if (text1.substring(text1.length - pointermid, text1.length - pointerend) == - text2.substring(text2.length - pointermid, text2.length - pointerend)) { - pointermin = pointermid; - pointerend = pointermin; - } else { - pointermax = pointermid; - } - pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); - } - return pointermid; -}; - - -/** - * Do the two texts share a substring which is at least half the length of the - * longer text? - * This speedup can produce non-minimal diffs. - * @param {string} text1 First string. - * @param {string} text2 Second string. - * @return {Array.} Five element Array, containing the prefix of - * text1, the suffix of text1, the prefix of text2, the suffix of - * text2 and the common middle. Or null if there was no match. - */ -function diff_halfMatch_(text1, text2) { - var longtext = text1.length > text2.length ? text1 : text2; - var shorttext = text1.length > text2.length ? text2 : text1; - if (longtext.length < 4 || shorttext.length * 2 < longtext.length) { - return null; // Pointless. - } - - /** - * Does a substring of shorttext exist within longtext such that the substring - * is at least half the length of longtext? - * Closure, but does not reference any external variables. - * @param {string} longtext Longer string. - * @param {string} shorttext Shorter string. - * @param {number} i Start index of quarter length substring within longtext. - * @return {Array.} Five element Array, containing the prefix of - * longtext, the suffix of longtext, the prefix of shorttext, the suffix - * of shorttext and the common middle. Or null if there was no match. - * @private - */ - function diff_halfMatchI_(longtext, shorttext, i) { - // Start with a 1/4 length substring at position i as a seed. - var seed = longtext.substring(i, i + Math.floor(longtext.length / 4)); - var j = -1; - var best_common = ''; - var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b; - while ((j = shorttext.indexOf(seed, j + 1)) != -1) { - var prefixLength = diff_commonPrefix(longtext.substring(i), - shorttext.substring(j)); - var suffixLength = diff_commonSuffix(longtext.substring(0, i), - shorttext.substring(0, j)); - if (best_common.length < suffixLength + prefixLength) { - best_common = shorttext.substring(j - suffixLength, j) + - shorttext.substring(j, j + prefixLength); - best_longtext_a = longtext.substring(0, i - suffixLength); - best_longtext_b = longtext.substring(i + prefixLength); - best_shorttext_a = shorttext.substring(0, j - suffixLength); - best_shorttext_b = shorttext.substring(j + prefixLength); - } - } - if (best_common.length * 2 >= longtext.length) { - return [best_longtext_a, best_longtext_b, - best_shorttext_a, best_shorttext_b, best_common]; - } else { - return null; - } - } - - // First check if the second quarter is the seed for a half-match. - var hm1 = diff_halfMatchI_(longtext, shorttext, - Math.ceil(longtext.length / 4)); - // Check again based on the third quarter. - var hm2 = diff_halfMatchI_(longtext, shorttext, - Math.ceil(longtext.length / 2)); - var hm; - if (!hm1 && !hm2) { - return null; - } else if (!hm2) { - hm = hm1; - } else if (!hm1) { - hm = hm2; - } else { - // Both matched. Select the longest. - hm = hm1[4].length > hm2[4].length ? hm1 : hm2; - } - - // A half-match was found, sort out the return data. - var text1_a, text1_b, text2_a, text2_b; - if (text1.length > text2.length) { - text1_a = hm[0]; - text1_b = hm[1]; - text2_a = hm[2]; - text2_b = hm[3]; - } else { - text2_a = hm[0]; - text2_b = hm[1]; - text1_a = hm[2]; - text1_b = hm[3]; - } - var mid_common = hm[4]; - return [text1_a, text1_b, text2_a, text2_b, mid_common]; -}; - - -/** - * Reorder and merge like edit sections. Merge equalities. - * Any edit section can move as long as it doesn't cross an equality. - * @param {Array} diffs Array of diff tuples. - */ -function diff_cleanupMerge(diffs) { - diffs.push([DIFF_EQUAL, '']); // Add a dummy entry at the end. - var pointer = 0; - var count_delete = 0; - var count_insert = 0; - var text_delete = ''; - var text_insert = ''; - var commonlength; - while (pointer < diffs.length) { - switch (diffs[pointer][0]) { - case DIFF_INSERT: - count_insert++; - text_insert += diffs[pointer][1]; - pointer++; - break; - case DIFF_DELETE: - count_delete++; - text_delete += diffs[pointer][1]; - pointer++; - break; - case DIFF_EQUAL: - // Upon reaching an equality, check for prior redundancies. - if (count_delete + count_insert > 1) { - if (count_delete !== 0 && count_insert !== 0) { - // Factor out any common prefixies. - commonlength = diff_commonPrefix(text_insert, text_delete); - if (commonlength !== 0) { - if ((pointer - count_delete - count_insert) > 0 && - diffs[pointer - count_delete - count_insert - 1][0] == - DIFF_EQUAL) { - diffs[pointer - count_delete - count_insert - 1][1] += - text_insert.substring(0, commonlength); - } else { - diffs.splice(0, 0, [DIFF_EQUAL, - text_insert.substring(0, commonlength)]); - pointer++; - } - text_insert = text_insert.substring(commonlength); - text_delete = text_delete.substring(commonlength); - } - // Factor out any common suffixies. - commonlength = diff_commonSuffix(text_insert, text_delete); - if (commonlength !== 0) { - diffs[pointer][1] = text_insert.substring(text_insert.length - - commonlength) + diffs[pointer][1]; - text_insert = text_insert.substring(0, text_insert.length - - commonlength); - text_delete = text_delete.substring(0, text_delete.length - - commonlength); - } - } - // Delete the offending records and add the merged ones. - if (count_delete === 0) { - diffs.splice(pointer - count_insert, - count_delete + count_insert, [DIFF_INSERT, text_insert]); - } else if (count_insert === 0) { - diffs.splice(pointer - count_delete, - count_delete + count_insert, [DIFF_DELETE, text_delete]); - } else { - diffs.splice(pointer - count_delete - count_insert, - count_delete + count_insert, [DIFF_DELETE, text_delete], - [DIFF_INSERT, text_insert]); - } - pointer = pointer - count_delete - count_insert + - (count_delete ? 1 : 0) + (count_insert ? 1 : 0) + 1; - } else if (pointer !== 0 && diffs[pointer - 1][0] == DIFF_EQUAL) { - // Merge this equality with the previous one. - diffs[pointer - 1][1] += diffs[pointer][1]; - diffs.splice(pointer, 1); - } else { - pointer++; - } - count_insert = 0; - count_delete = 0; - text_delete = ''; - text_insert = ''; - break; - } - } - if (diffs[diffs.length - 1][1] === '') { - diffs.pop(); // Remove the dummy entry at the end. - } - - // Second pass: look for single edits surrounded on both sides by equalities - // which can be shifted sideways to eliminate an equality. - // e.g: ABAC -> ABAC - var changes = false; - pointer = 1; - // Intentionally ignore the first and last element (don't need checking). - while (pointer < diffs.length - 1) { - if (diffs[pointer - 1][0] == DIFF_EQUAL && - diffs[pointer + 1][0] == DIFF_EQUAL) { - // This is a single edit surrounded by equalities. - if (diffs[pointer][1].substring(diffs[pointer][1].length - - diffs[pointer - 1][1].length) == diffs[pointer - 1][1]) { - // Shift the edit over the previous equality. - diffs[pointer][1] = diffs[pointer - 1][1] + - diffs[pointer][1].substring(0, diffs[pointer][1].length - - diffs[pointer - 1][1].length); - diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1]; - diffs.splice(pointer - 1, 1); - changes = true; - } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) == - diffs[pointer + 1][1]) { - // Shift the edit over the next equality. - diffs[pointer - 1][1] += diffs[pointer + 1][1]; - diffs[pointer][1] = - diffs[pointer][1].substring(diffs[pointer + 1][1].length) + - diffs[pointer + 1][1]; - diffs.splice(pointer + 1, 1); - changes = true; - } - } - pointer++; - } - // If shifts were made, the diff needs reordering and another shift sweep. - if (changes) { - diff_cleanupMerge(diffs); - } -}; - - -var diff = diff_main; -diff.INSERT = DIFF_INSERT; -diff.DELETE = DIFF_DELETE; -diff.EQUAL = DIFF_EQUAL; - -module.exports = diff; - -/* - * Modify a diff such that the cursor position points to the start of a change: - * E.g. - * cursor_normalize_diff([[DIFF_EQUAL, 'abc']], 1) - * => [1, [[DIFF_EQUAL, 'a'], [DIFF_EQUAL, 'bc']]] - * cursor_normalize_diff([[DIFF_INSERT, 'new'], [DIFF_DELETE, 'xyz']], 2) - * => [2, [[DIFF_INSERT, 'new'], [DIFF_DELETE, 'xy'], [DIFF_DELETE, 'z']]] - * - * @param {Array} diffs Array of diff tuples - * @param {Int} cursor_pos Suggested edit position. Must not be out of bounds! - * @return {Array} A tuple [cursor location in the modified diff, modified diff] - */ -function cursor_normalize_diff (diffs, cursor_pos) { - if (cursor_pos === 0) { - return [DIFF_EQUAL, diffs]; - } - for (var current_pos = 0, i = 0; i < diffs.length; i++) { - var d = diffs[i]; - if (d[0] === DIFF_DELETE || d[0] === DIFF_EQUAL) { - var next_pos = current_pos + d[1].length; - if (cursor_pos === next_pos) { - return [i + 1, diffs]; - } else if (cursor_pos < next_pos) { - // copy to prevent side effects - diffs = diffs.slice(); - // split d into two diff changes - var split_pos = cursor_pos - current_pos; - var d_left = [d[0], d[1].slice(0, split_pos)]; - var d_right = [d[0], d[1].slice(split_pos)]; - diffs.splice(i, 1, d_left, d_right); - return [i + 1, diffs]; - } else { - current_pos = next_pos; - } - } - } - throw new Error('cursor_pos is out of bounds!') -} - -/* - * Modify a diff such that the edit position is "shifted" to the proposed edit location (cursor_position). - * - * Case 1) - * Check if a naive shift is possible: - * [0, X], [ 1, Y] -> [ 1, Y], [0, X] (if X + Y === Y + X) - * [0, X], [-1, Y] -> [-1, Y], [0, X] (if X + Y === Y + X) - holds same result - * Case 2) - * Check if the following shifts are possible: - * [0, 'pre'], [ 1, 'prefix'] -> [ 1, 'pre'], [0, 'pre'], [ 1, 'fix'] - * [0, 'pre'], [-1, 'prefix'] -> [-1, 'pre'], [0, 'pre'], [-1, 'fix'] - * ^ ^ - * d d_next - * - * @param {Array} diffs Array of diff tuples - * @param {Int} cursor_pos Suggested edit position. Must not be out of bounds! - * @return {Array} Array of diff tuples - */ -function fix_cursor (diffs, cursor_pos) { - var norm = cursor_normalize_diff(diffs, cursor_pos); - var ndiffs = norm[1]; - var cursor_pointer = norm[0]; - var d = ndiffs[cursor_pointer]; - var d_next = ndiffs[cursor_pointer + 1]; - - if (d == null) { - // Text was deleted from end of original string, - // cursor is now out of bounds in new string - return diffs; - } else if (d[0] !== DIFF_EQUAL) { - // A modification happened at the cursor location. - // This is the expected outcome, so we can return the original diff. - return diffs; - } else { - if (d_next != null && d[1] + d_next[1] === d_next[1] + d[1]) { - // Case 1) - // It is possible to perform a naive shift - ndiffs.splice(cursor_pointer, 2, d_next, d) - return merge_tuples(ndiffs, cursor_pointer, 2) - } else if (d_next != null && d_next[1].indexOf(d[1]) === 0) { - // Case 2) - // d[1] is a prefix of d_next[1] - // We can assume that d_next[0] !== 0, since d[0] === 0 - // Shift edit locations.. - ndiffs.splice(cursor_pointer, 2, [d_next[0], d[1]], [0, d[1]]); - var suffix = d_next[1].slice(d[1].length); - if (suffix.length > 0) { - ndiffs.splice(cursor_pointer + 2, 0, [d_next[0], suffix]); - } - return merge_tuples(ndiffs, cursor_pointer, 3) - } else { - // Not possible to perform any modification - return diffs; - } - } -} - -/* - * Check diff did not split surrogate pairs. - * Ex. [0, '\uD83D'], [-1, '\uDC36'], [1, '\uDC2F'] -> [-1, '\uD83D\uDC36'], [1, '\uD83D\uDC2F'] - * '\uD83D\uDC36' === '🐶', '\uD83D\uDC2F' === '🐯' - * - * @param {Array} diffs Array of diff tuples - * @return {Array} Array of diff tuples - */ -function fix_emoji (diffs) { - var compact = false; - var starts_with_pair_end = function(str) { - return str.charCodeAt(0) >= 0xDC00 && str.charCodeAt(0) <= 0xDFFF; - } - var ends_with_pair_start = function(str) { - return str.charCodeAt(str.length-1) >= 0xD800 && str.charCodeAt(str.length-1) <= 0xDBFF; - } - for (var i = 2; i < diffs.length; i += 1) { - if (diffs[i-2][0] === DIFF_EQUAL && ends_with_pair_start(diffs[i-2][1]) && - diffs[i-1][0] === DIFF_DELETE && starts_with_pair_end(diffs[i-1][1]) && - diffs[i][0] === DIFF_INSERT && starts_with_pair_end(diffs[i][1])) { - compact = true; - - diffs[i-1][1] = diffs[i-2][1].slice(-1) + diffs[i-1][1]; - diffs[i][1] = diffs[i-2][1].slice(-1) + diffs[i][1]; - - diffs[i-2][1] = diffs[i-2][1].slice(0, -1); - } - } - if (!compact) { - return diffs; - } - var fixed_diffs = []; - for (var i = 0; i < diffs.length; i += 1) { - if (diffs[i][1].length > 0) { - fixed_diffs.push(diffs[i]); - } - } - return fixed_diffs; -} - -/* - * Try to merge tuples with their neigbors in a given range. - * E.g. [0, 'a'], [0, 'b'] -> [0, 'ab'] - * - * @param {Array} diffs Array of diff tuples. - * @param {Int} start Position of the first element to merge (diffs[start] is also merged with diffs[start - 1]). - * @param {Int} length Number of consecutive elements to check. - * @return {Array} Array of merged diff tuples. - */ -function merge_tuples (diffs, start, length) { - // Check from (start-1) to (start+length). - for (var i = start + length - 1; i >= 0 && i >= start - 1; i--) { - if (i + 1 < diffs.length) { - var left_d = diffs[i]; - var right_d = diffs[i+1]; - if (left_d[0] === right_d[1]) { - diffs.splice(i, 2, [left_d[0], left_d[1] + right_d[1]]); - } - } - } - return diffs; -} - - -/***/ }), -/* 52 */ -/***/ (function(module, exports) { - -exports = module.exports = typeof Object.keys === 'function' - ? Object.keys : shim; - -exports.shim = shim; -function shim (obj) { - var keys = []; - for (var key in obj) keys.push(key); - return keys; -} - - -/***/ }), -/* 53 */ -/***/ (function(module, exports) { - -var supportsArgumentsClass = (function(){ - return Object.prototype.toString.call(arguments) -})() == '[object Arguments]'; - -exports = module.exports = supportsArgumentsClass ? supported : unsupported; - -exports.supported = supported; -function supported(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -}; - -exports.unsupported = unsupported; -function unsupported(object){ - return object && - typeof object == 'object' && - typeof object.length == 'number' && - Object.prototype.hasOwnProperty.call(object, 'callee') && - !Object.prototype.propertyIsEnumerable.call(object, 'callee') || - false; -}; - - -/***/ }), -/* 54 */ -/***/ (function(module, exports) { - -'use strict'; - -var has = Object.prototype.hasOwnProperty - , prefix = '~'; - -/** - * Constructor to create a storage for our `EE` objects. - * An `Events` instance is a plain object whose properties are event names. - * - * @constructor - * @api private - */ -function Events() {} - -// -// We try to not inherit from `Object.prototype`. In some engines creating an -// instance in this way is faster than calling `Object.create(null)` directly. -// If `Object.create(null)` is not supported we prefix the event names with a -// character to make sure that the built-in object properties are not -// overridden or used as an attack vector. -// -if (Object.create) { - Events.prototype = Object.create(null); - - // - // This hack is needed because the `__proto__` property is still inherited in - // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. - // - if (!new Events().__proto__) prefix = false; -} - -/** - * Representation of a single event listener. - * - * @param {Function} fn The listener function. - * @param {Mixed} context The context to invoke the listener with. - * @param {Boolean} [once=false] Specify if the listener is a one-time listener. - * @constructor - * @api private - */ -function EE(fn, context, once) { - this.fn = fn; - this.context = context; - this.once = once || false; -} - -/** - * Minimal `EventEmitter` interface that is molded against the Node.js - * `EventEmitter` interface. - * - * @constructor - * @api public - */ -function EventEmitter() { - this._events = new Events(); - this._eventsCount = 0; -} - -/** - * Return an array listing the events for which the emitter has registered - * listeners. - * - * @returns {Array} - * @api public - */ -EventEmitter.prototype.eventNames = function eventNames() { - var names = [] - , events - , name; - - if (this._eventsCount === 0) return names; - - for (name in (events = this._events)) { - if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); - } - - if (Object.getOwnPropertySymbols) { - return names.concat(Object.getOwnPropertySymbols(events)); - } - - return names; -}; - -/** - * Return the listeners registered for a given event. - * - * @param {String|Symbol} event The event name. - * @param {Boolean} exists Only check if there are listeners. - * @returns {Array|Boolean} - * @api public - */ -EventEmitter.prototype.listeners = function listeners(event, exists) { - var evt = prefix ? prefix + event : event - , available = this._events[evt]; - - if (exists) return !!available; - if (!available) return []; - if (available.fn) return [available.fn]; - - for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) { - ee[i] = available[i].fn; - } - - return ee; -}; - -/** - * Calls each of the listeners registered for a given event. - * - * @param {String|Symbol} event The event name. - * @returns {Boolean} `true` if the event had listeners, else `false`. - * @api public - */ -EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { - var evt = prefix ? prefix + event : event; - - if (!this._events[evt]) return false; - - var listeners = this._events[evt] - , len = arguments.length - , args - , i; - - if (listeners.fn) { - if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); - - switch (len) { - case 1: return listeners.fn.call(listeners.context), true; - case 2: return listeners.fn.call(listeners.context, a1), true; - case 3: return listeners.fn.call(listeners.context, a1, a2), true; - case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; - case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; - case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; - } - - for (i = 1, args = new Array(len -1); i < len; i++) { - args[i - 1] = arguments[i]; - } - - listeners.fn.apply(listeners.context, args); - } else { - var length = listeners.length - , j; - - for (i = 0; i < length; i++) { - if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); - - switch (len) { - case 1: listeners[i].fn.call(listeners[i].context); break; - case 2: listeners[i].fn.call(listeners[i].context, a1); break; - case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; - case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; - default: - if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { - args[j - 1] = arguments[j]; - } - - listeners[i].fn.apply(listeners[i].context, args); - } - } - } - - return true; -}; - -/** - * Add a listener for a given event. - * - * @param {String|Symbol} event The event name. - * @param {Function} fn The listener function. - * @param {Mixed} [context=this] The context to invoke the listener with. - * @returns {EventEmitter} `this`. - * @api public - */ -EventEmitter.prototype.on = function on(event, fn, context) { - var listener = new EE(fn, context || this) - , evt = prefix ? prefix + event : event; - - if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++; - else if (!this._events[evt].fn) this._events[evt].push(listener); - else this._events[evt] = [this._events[evt], listener]; - - return this; -}; - -/** - * Add a one-time listener for a given event. - * - * @param {String|Symbol} event The event name. - * @param {Function} fn The listener function. - * @param {Mixed} [context=this] The context to invoke the listener with. - * @returns {EventEmitter} `this`. - * @api public - */ -EventEmitter.prototype.once = function once(event, fn, context) { - var listener = new EE(fn, context || this, true) - , evt = prefix ? prefix + event : event; - - if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++; - else if (!this._events[evt].fn) this._events[evt].push(listener); - else this._events[evt] = [this._events[evt], listener]; - - return this; -}; - -/** - * Remove the listeners of a given event. - * - * @param {String|Symbol} event The event name. - * @param {Function} fn Only remove the listeners that match this function. - * @param {Mixed} context Only remove the listeners that have this context. - * @param {Boolean} once Only remove one-time listeners. - * @returns {EventEmitter} `this`. - * @api public - */ -EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { - var evt = prefix ? prefix + event : event; - - if (!this._events[evt]) return this; - if (!fn) { - if (--this._eventsCount === 0) this._events = new Events(); - else delete this._events[evt]; - return this; - } - - var listeners = this._events[evt]; - - if (listeners.fn) { - if ( - listeners.fn === fn - && (!once || listeners.once) - && (!context || listeners.context === context) - ) { - if (--this._eventsCount === 0) this._events = new Events(); - else delete this._events[evt]; - } - } else { - for (var i = 0, events = [], length = listeners.length; i < length; i++) { - if ( - listeners[i].fn !== fn - || (once && !listeners[i].once) - || (context && listeners[i].context !== context) - ) { - events.push(listeners[i]); - } - } - - // - // Reset the array, or remove it completely if we have no more listeners. - // - if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; - else if (--this._eventsCount === 0) this._events = new Events(); - else delete this._events[evt]; - } - - return this; -}; - -/** - * Remove all listeners, or those of the specified event. - * - * @param {String|Symbol} [event] The event name. - * @returns {EventEmitter} `this`. - * @api public - */ -EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { - var evt; - - if (event) { - evt = prefix ? prefix + event : event; - if (this._events[evt]) { - if (--this._eventsCount === 0) this._events = new Events(); - else delete this._events[evt]; - } - } else { - this._events = new Events(); - this._eventsCount = 0; - } - - return this; -}; - -// -// Alias methods names because people roll like that. -// -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; -EventEmitter.prototype.addListener = EventEmitter.prototype.on; - -// -// This function doesn't apply anymore. -// -EventEmitter.prototype.setMaxListeners = function setMaxListeners() { - return this; -}; - -// -// Expose the prefix. -// -EventEmitter.prefixed = prefix; - -// -// Allow `EventEmitter` to be imported as module namespace. -// -EventEmitter.EventEmitter = EventEmitter; - -// -// Expose the module. -// -if ('undefined' !== typeof module) { - module.exports = EventEmitter; -} - - -/***/ }), -/* 55 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.matchText = exports.matchSpacing = exports.matchNewline = exports.matchBlot = exports.matchAttributor = exports.default = undefined; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _extend2 = __webpack_require__(3); - -var _extend3 = _interopRequireDefault(_extend2); - -var _quillDelta = __webpack_require__(2); - -var _quillDelta2 = _interopRequireDefault(_quillDelta); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _quill = __webpack_require__(5); - -var _quill2 = _interopRequireDefault(_quill); - -var _logger = __webpack_require__(10); - -var _logger2 = _interopRequireDefault(_logger); - -var _module = __webpack_require__(9); - -var _module2 = _interopRequireDefault(_module); - -var _align = __webpack_require__(36); - -var _background = __webpack_require__(37); - -var _code = __webpack_require__(13); - -var _code2 = _interopRequireDefault(_code); - -var _color = __webpack_require__(26); - -var _direction = __webpack_require__(38); - -var _font = __webpack_require__(39); - -var _size = __webpack_require__(40); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var debug = (0, _logger2.default)('quill:clipboard'); - -var DOM_KEY = '__ql-matcher'; - -var CLIPBOARD_CONFIG = [[Node.TEXT_NODE, matchText], [Node.TEXT_NODE, matchNewline], ['br', matchBreak], [Node.ELEMENT_NODE, matchNewline], [Node.ELEMENT_NODE, matchBlot], [Node.ELEMENT_NODE, matchSpacing], [Node.ELEMENT_NODE, matchAttributor], [Node.ELEMENT_NODE, matchStyles], ['li', matchIndent], ['b', matchAlias.bind(matchAlias, 'bold')], ['i', matchAlias.bind(matchAlias, 'italic')], ['style', matchIgnore]]; - -var ATTRIBUTE_ATTRIBUTORS = [_align.AlignAttribute, _direction.DirectionAttribute].reduce(function (memo, attr) { - memo[attr.keyName] = attr; - return memo; -}, {}); - -var STYLE_ATTRIBUTORS = [_align.AlignStyle, _background.BackgroundStyle, _color.ColorStyle, _direction.DirectionStyle, _font.FontStyle, _size.SizeStyle].reduce(function (memo, attr) { - memo[attr.keyName] = attr; - return memo; -}, {}); - -var Clipboard = function (_Module) { - _inherits(Clipboard, _Module); - - function Clipboard(quill, options) { - _classCallCheck(this, Clipboard); - - var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this, quill, options)); - - _this.quill.root.addEventListener('paste', _this.onPaste.bind(_this)); - _this.container = _this.quill.addContainer('ql-clipboard'); - _this.container.setAttribute('contenteditable', true); - _this.container.setAttribute('tabindex', -1); - _this.matchers = []; - CLIPBOARD_CONFIG.concat(_this.options.matchers).forEach(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - selector = _ref2[0], - matcher = _ref2[1]; - - if (!options.matchVisual && matcher === matchSpacing) return; - _this.addMatcher(selector, matcher); - }); - return _this; - } - - _createClass(Clipboard, [{ - key: 'addMatcher', - value: function addMatcher(selector, matcher) { - this.matchers.push([selector, matcher]); - } - }, { - key: 'convert', - value: function convert(html) { - if (typeof html === 'string') { - this.container.innerHTML = html.replace(/\>\r?\n +\<'); // Remove spaces between tags - - return this.convert(); - } - - var formats = this.quill.getFormat(this.quill.selection.savedRange.index); - if (formats[_code2.default.blotName]) { - var text = this.container.innerText; - this.container.innerHTML = ''; - return new _quillDelta2.default().insert(text, _defineProperty({}, _code2.default.blotName, formats[_code2.default.blotName])); - } - - var _prepareMatching = this.prepareMatching(), - _prepareMatching2 = _slicedToArray(_prepareMatching, 2), - elementMatchers = _prepareMatching2[0], - textMatchers = _prepareMatching2[1]; - - var delta = traverse(this.container, elementMatchers, textMatchers); - // Remove trailing newline - if (deltaEndsWith(delta, '\n') && delta.ops[delta.ops.length - 1].attributes == null) { - delta = delta.compose(new _quillDelta2.default().retain(delta.length() - 1).delete(1)); - } - debug.log('convert', this.container.innerHTML, delta); - this.container.innerHTML = ''; - return delta; - } - }, { - key: 'dangerouslyPasteHTML', - value: function dangerouslyPasteHTML(index, html) { - var source = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _quill2.default.sources.API; - - if (typeof index === 'string') { - this.quill.setContents(this.convert(index), html); - this.quill.setSelection(0, _quill2.default.sources.SILENT); - } else { - var paste = this.convert(html); - this.quill.updateContents(new _quillDelta2.default().retain(index).concat(paste), source); - this.quill.setSelection(index + paste.length(), _quill2.default.sources.SILENT); - } - } - }, { - key: 'onPaste', - value: function onPaste(e) { - var _this2 = this; - - if (e.defaultPrevented || !this.quill.isEnabled()) return; - var range = this.quill.getSelection(); - var delta = new _quillDelta2.default().retain(range.index); - var scrollTop = this.quill.scrollingContainer.scrollTop; - this.container.focus(); - this.quill.selection.update(_quill2.default.sources.SILENT); - setTimeout(function () { - delta = delta.concat(_this2.convert()).delete(range.length); - _this2.quill.updateContents(delta, _quill2.default.sources.USER); - // range.length contributes to delta.length() - _this2.quill.setSelection(delta.length() - range.length, _quill2.default.sources.SILENT); - _this2.quill.scrollingContainer.scrollTop = scrollTop; - _this2.quill.focus(); - }, 1); - } - }, { - key: 'prepareMatching', - value: function prepareMatching() { - var _this3 = this; - - var elementMatchers = [], - textMatchers = []; - this.matchers.forEach(function (pair) { - var _pair = _slicedToArray(pair, 2), - selector = _pair[0], - matcher = _pair[1]; - - switch (selector) { - case Node.TEXT_NODE: - textMatchers.push(matcher); - break; - case Node.ELEMENT_NODE: - elementMatchers.push(matcher); - break; - default: - [].forEach.call(_this3.container.querySelectorAll(selector), function (node) { - // TODO use weakmap - node[DOM_KEY] = node[DOM_KEY] || []; - node[DOM_KEY].push(matcher); - }); - break; - } - }); - return [elementMatchers, textMatchers]; - } - }]); - - return Clipboard; -}(_module2.default); - -Clipboard.DEFAULTS = { - matchers: [], - matchVisual: true -}; - -function applyFormat(delta, format, value) { - if ((typeof format === 'undefined' ? 'undefined' : _typeof(format)) === 'object') { - return Object.keys(format).reduce(function (delta, key) { - return applyFormat(delta, key, format[key]); - }, delta); - } else { - return delta.reduce(function (delta, op) { - if (op.attributes && op.attributes[format]) { - return delta.push(op); - } else { - return delta.insert(op.insert, (0, _extend3.default)({}, _defineProperty({}, format, value), op.attributes)); - } - }, new _quillDelta2.default()); - } -} - -function computeStyle(node) { - if (node.nodeType !== Node.ELEMENT_NODE) return {}; - var DOM_KEY = '__ql-computed-style'; - return node[DOM_KEY] || (node[DOM_KEY] = window.getComputedStyle(node)); -} - -function deltaEndsWith(delta, text) { - var endText = ""; - for (var i = delta.ops.length - 1; i >= 0 && endText.length < text.length; --i) { - var op = delta.ops[i]; - if (typeof op.insert !== 'string') break; - endText = op.insert + endText; - } - return endText.slice(-1 * text.length) === text; -} - -function isLine(node) { - if (node.childNodes.length === 0) return false; // Exclude embed blocks - var style = computeStyle(node); - - // This is a fix. window.getComputedStyle(node) returns a CSSStyleDeclaration - // but all the properties are empty. This causes newline characters to be missed - if (node.nodeName === 'P' || node.nodeName === 'LI' || node.nodeName === 'UL') { - return true; - } - - return ['block', 'list-item'].indexOf(style.display) > -1; -} - -function traverse(node, elementMatchers, textMatchers) { - // Post-order - if (node.nodeType === node.TEXT_NODE) { - return textMatchers.reduce(function (delta, matcher) { - return matcher(node, delta); - }, new _quillDelta2.default()); - } else if (node.nodeType === node.ELEMENT_NODE) { - return [].reduce.call(node.childNodes || [], function (delta, childNode) { - var childrenDelta = traverse(childNode, elementMatchers, textMatchers); - if (childNode.nodeType === node.ELEMENT_NODE) { - childrenDelta = elementMatchers.reduce(function (childrenDelta, matcher) { - return matcher(childNode, childrenDelta); - }, childrenDelta); - childrenDelta = (childNode[DOM_KEY] || []).reduce(function (childrenDelta, matcher) { - return matcher(childNode, childrenDelta); - }, childrenDelta); - } - return delta.concat(childrenDelta); - }, new _quillDelta2.default()); - } else { - return new _quillDelta2.default(); - } -} - -function matchAlias(format, node, delta) { - return applyFormat(delta, format, true); -} - -function matchAttributor(node, delta) { - var attributes = _parchment2.default.Attributor.Attribute.keys(node); - var classes = _parchment2.default.Attributor.Class.keys(node); - var styles = _parchment2.default.Attributor.Style.keys(node); - var formats = {}; - attributes.concat(classes).concat(styles).forEach(function (name) { - var attr = _parchment2.default.query(name, _parchment2.default.Scope.ATTRIBUTE); - if (attr != null) { - formats[attr.attrName] = attr.value(node); - if (formats[attr.attrName]) return; - } - attr = ATTRIBUTE_ATTRIBUTORS[name]; - if (attr != null && (attr.attrName === name || attr.keyName === name)) { - formats[attr.attrName] = attr.value(node) || undefined; - } - attr = STYLE_ATTRIBUTORS[name]; - if (attr != null && (attr.attrName === name || attr.keyName === name)) { - attr = STYLE_ATTRIBUTORS[name]; - formats[attr.attrName] = attr.value(node) || undefined; - } - }); - if (Object.keys(formats).length > 0) { - delta = applyFormat(delta, formats); - } - return delta; -} - -function matchBlot(node, delta) { - var match = _parchment2.default.query(node); - if (match == null) return delta; - if (match.prototype instanceof _parchment2.default.Embed) { - var embed = {}; - var value = match.value(node); - if (value != null) { - embed[match.blotName] = value; - delta = new _quillDelta2.default().insert(embed, match.formats(node)); - } - } else if (typeof match.formats === 'function') { - delta = applyFormat(delta, match.blotName, match.formats(node)); - } - return delta; -} - -function matchBreak(node, delta) { - if (!deltaEndsWith(delta, '\n')) { - delta.insert('\n'); - } - return delta; -} - -function matchIgnore() { - return new _quillDelta2.default(); -} - -function matchIndent(node, delta) { - var match = _parchment2.default.query(node); - if (match == null || match.blotName !== 'list-item' || !deltaEndsWith(delta, '\n')) { - return delta; - } - var indent = -1, - parent = node.parentNode; - while (!parent.classList.contains('ql-clipboard')) { - if ((_parchment2.default.query(parent) || {}).blotName === 'list') { - indent += 1; - } - parent = parent.parentNode; - } - if (indent <= 0) return delta; - return delta.compose(new _quillDelta2.default().retain(delta.length() - 1).retain(1, { indent: indent })); -} - -function matchNewline(node, delta) { - if (!deltaEndsWith(delta, '\n')) { - if (isLine(node) || (delta.length() > 0 && node.nextSibling && isLine(node.nextSibling))) { - delta.insert('\n'); - } - } - return delta; -} - -function matchSpacing(node, delta) { - if (isLine(node) && node.nextElementSibling != null && !deltaEndsWith(delta, '\n\n')) { - var nodeHeight = node.offsetHeight + parseFloat(computeStyle(node).marginTop) + parseFloat(computeStyle(node).marginBottom); - if (node.nextElementSibling.offsetTop > node.offsetTop + nodeHeight * 1.5) { - delta.insert('\n'); - } - } - return delta; -} - -function matchStyles(node, delta) { - var formats = {}; - var style = node.style || {}; - if (style.fontStyle && computeStyle(node).fontStyle === 'italic') { - formats.italic = true; - } - if (style.fontWeight && (computeStyle(node).fontWeight.startsWith('bold') || parseInt(computeStyle(node).fontWeight) >= 700)) { - formats.bold = true; - } - if (Object.keys(formats).length > 0) { - delta = applyFormat(delta, formats); - } - if (parseFloat(style.textIndent || 0) > 0) { - // Could be 0.5in - delta = new _quillDelta2.default().insert('\t').concat(delta); - } - return delta; -} - -function matchText(node, delta) { - var text = node.data; - // Word represents empty line with   - if (node.parentNode.tagName === 'O:P') { - return delta.insert(text.trim()); - } - if (text.trim().length === 0 && node.parentNode.classList.contains('ql-clipboard')) { - return delta; - } - if (!computeStyle(node.parentNode).whiteSpace.startsWith('pre')) { - // eslint-disable-next-line func-style - var replacer = function replacer(collapse, match) { - match = match.replace(/[^\u00a0]/g, ''); // \u00a0 is nbsp; - return match.length < 1 && collapse ? ' ' : match; - }; - text = text.replace(/\r\n/g, ' ').replace(/\n/g, ' '); - text = text.replace(/\s\s+/g, replacer.bind(replacer, true)); // collapse whitespace - if (node.previousSibling == null && isLine(node.parentNode) || node.previousSibling != null && isLine(node.previousSibling)) { - text = text.replace(/^\s+/, replacer.bind(replacer, false)); - } - if (node.nextSibling == null && isLine(node.parentNode) || node.nextSibling != null && isLine(node.nextSibling)) { - text = text.replace(/\s+$/, replacer.bind(replacer, false)); - } - } - return delta.insert(text); -} - -exports.default = Clipboard; -exports.matchAttributor = matchAttributor; -exports.matchBlot = matchBlot; -exports.matchNewline = matchNewline; -exports.matchSpacing = matchSpacing; -exports.matchText = matchText; - -/***/ }), -/* 56 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _inline = __webpack_require__(6); - -var _inline2 = _interopRequireDefault(_inline); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Bold = function (_Inline) { - _inherits(Bold, _Inline); - - function Bold() { - _classCallCheck(this, Bold); - - return _possibleConstructorReturn(this, (Bold.__proto__ || Object.getPrototypeOf(Bold)).apply(this, arguments)); - } - - _createClass(Bold, [{ - key: 'optimize', - value: function optimize(context) { - _get(Bold.prototype.__proto__ || Object.getPrototypeOf(Bold.prototype), 'optimize', this).call(this, context); - if (this.domNode.tagName !== this.statics.tagName[0]) { - this.replaceWith(this.statics.blotName); - } - } - }], [{ - key: 'create', - value: function create() { - return _get(Bold.__proto__ || Object.getPrototypeOf(Bold), 'create', this).call(this); - } - }, { - key: 'formats', - value: function formats() { - return true; - } - }]); - - return Bold; -}(_inline2.default); - -Bold.blotName = 'bold'; -Bold.tagName = ['STRONG', 'B']; - -exports.default = Bold; - -/***/ }), -/* 57 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.addControls = exports.default = undefined; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _quillDelta = __webpack_require__(2); - -var _quillDelta2 = _interopRequireDefault(_quillDelta); - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _quill = __webpack_require__(5); - -var _quill2 = _interopRequireDefault(_quill); - -var _logger = __webpack_require__(10); - -var _logger2 = _interopRequireDefault(_logger); - -var _module = __webpack_require__(9); - -var _module2 = _interopRequireDefault(_module); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var debug = (0, _logger2.default)('quill:toolbar'); - -var Toolbar = function (_Module) { - _inherits(Toolbar, _Module); - - function Toolbar(quill, options) { - _classCallCheck(this, Toolbar); - - var _this = _possibleConstructorReturn(this, (Toolbar.__proto__ || Object.getPrototypeOf(Toolbar)).call(this, quill, options)); - - if (Array.isArray(_this.options.container)) { - var container = document.createElement('div'); - addControls(container, _this.options.container); - quill.container.parentNode.insertBefore(container, quill.container); - _this.container = container; - } else if (typeof _this.options.container === 'string') { - _this.container = document.querySelector(_this.options.container); - } else { - _this.container = _this.options.container; - } - if (!(_this.container instanceof HTMLElement)) { - var _ret; - - return _ret = debug.error('Container required for toolbar', _this.options), _possibleConstructorReturn(_this, _ret); - } - _this.container.classList.add('ql-toolbar'); - _this.controls = []; - _this.handlers = {}; - Object.keys(_this.options.handlers).forEach(function (format) { - _this.addHandler(format, _this.options.handlers[format]); - }); - [].forEach.call(_this.container.querySelectorAll('button, select'), function (input) { - _this.attach(input); - }); - _this.quill.on(_quill2.default.events.EDITOR_CHANGE, function (type, range) { - if (type === _quill2.default.events.SELECTION_CHANGE) { - _this.update(range); - } - }); - _this.quill.on(_quill2.default.events.SCROLL_OPTIMIZE, function () { - var _this$quill$selection = _this.quill.selection.getRange(), - _this$quill$selection2 = _slicedToArray(_this$quill$selection, 1), - range = _this$quill$selection2[0]; // quill.getSelection triggers update - - - _this.update(range); - }); - return _this; - } - - _createClass(Toolbar, [{ - key: 'addHandler', - value: function addHandler(format, handler) { - this.handlers[format] = handler; - } - }, { - key: 'attach', - value: function attach(input) { - var _this2 = this; - - var format = [].find.call(input.classList, function (className) { - return className.indexOf('ql-') === 0; - }); - if (!format) return; - format = format.slice('ql-'.length); - if (input.tagName === 'BUTTON') { - input.setAttribute('type', 'button'); - } - if (this.handlers[format] == null) { - if (this.quill.scroll.whitelist != null && this.quill.scroll.whitelist[format] == null) { - debug.warn('ignoring attaching to disabled format', format, input); - return; - } - if (_parchment2.default.query(format) == null) { - debug.warn('ignoring attaching to nonexistent format', format, input); - return; - } - } - var eventName = input.tagName === 'SELECT' ? 'change' : 'click'; - input.addEventListener(eventName, function (e) { - var value = void 0; - if (input.tagName === 'SELECT') { - if (input.selectedIndex < 0) return; - var selected = input.options[input.selectedIndex]; - if (selected.hasAttribute('selected')) { - value = false; - } else { - value = selected.value || false; - } - } else { - if (input.classList.contains('ql-active')) { - value = false; - } else { - value = input.value || !input.hasAttribute('value'); - } - e.preventDefault(); - } - _this2.quill.focus(); - - var _quill$selection$getR = _this2.quill.selection.getRange(), - _quill$selection$getR2 = _slicedToArray(_quill$selection$getR, 1), - range = _quill$selection$getR2[0]; - - if (_this2.handlers[format] != null) { - _this2.handlers[format].call(_this2, value); - } else if (_parchment2.default.query(format).prototype instanceof _parchment2.default.Embed) { - value = prompt('Enter ' + format); - if (!value) return; - _this2.quill.updateContents(new _quillDelta2.default().retain(range.index).delete(range.length).insert(_defineProperty({}, format, value)), _quill2.default.sources.USER); - } else { - _this2.quill.format(format, value, _quill2.default.sources.USER); - } - _this2.update(range); - }); - // TODO use weakmap - this.controls.push([format, input]); - } - }, { - key: 'update', - value: function update(range) { - var formats = range == null ? {} : this.quill.getFormat(range); - this.controls.forEach(function (pair) { - var _pair = _slicedToArray(pair, 2), - format = _pair[0], - input = _pair[1]; - - if (input.tagName === 'SELECT') { - var option = void 0; - if (range == null) { - option = null; - } else if (formats[format] == null) { - option = input.querySelector('option[selected]'); - } else if (!Array.isArray(formats[format])) { - var value = formats[format]; - if (typeof value === 'string') { - value = value.replace(/\"/g, '\\"'); - } - option = input.querySelector('option[value="' + value + '"]'); - } - if (option == null) { - input.value = ''; // TODO make configurable? - input.selectedIndex = -1; - } else { - option.selected = true; - } - } else { - if (range == null) { - input.classList.remove('ql-active'); - } else if (input.hasAttribute('value')) { - // both being null should match (default values) - // '1' should match with 1 (headers) - var isActive = formats[format] === input.getAttribute('value') || formats[format] != null && formats[format].toString() === input.getAttribute('value') || formats[format] == null && !input.getAttribute('value'); - input.classList.toggle('ql-active', isActive); - } else { - input.classList.toggle('ql-active', formats[format] != null); - } - } - }); - } - }]); - - return Toolbar; -}(_module2.default); - -Toolbar.DEFAULTS = {}; - -function addButton(container, format, value) { - var input = document.createElement('button'); - input.setAttribute('type', 'button'); - input.classList.add('ql-' + format); - if (value != null) { - input.value = value; - } - container.appendChild(input); -} - -function addControls(container, groups) { - if (!Array.isArray(groups[0])) { - groups = [groups]; - } - groups.forEach(function (controls) { - var group = document.createElement('span'); - group.classList.add('ql-formats'); - controls.forEach(function (control) { - if (typeof control === 'string') { - addButton(group, control); - } else { - var format = Object.keys(control)[0]; - var value = control[format]; - if (Array.isArray(value)) { - addSelect(group, format, value); - } else { - addButton(group, format, value); - } - } - }); - container.appendChild(group); - }); -} - -function addSelect(container, format, values) { - var input = document.createElement('select'); - input.classList.add('ql-' + format); - values.forEach(function (value) { - var option = document.createElement('option'); - if (value !== false) { - option.setAttribute('value', value); - } else { - option.setAttribute('selected', 'selected'); - } - input.appendChild(option); - }); - container.appendChild(input); -} - -Toolbar.DEFAULTS = { - container: null, - handlers: { - clean: function clean() { - var _this3 = this; - - var range = this.quill.getSelection(); - if (range == null) return; - if (range.length == 0) { - var formats = this.quill.getFormat(); - Object.keys(formats).forEach(function (name) { - // Clean functionality in existing apps only clean inline formats - if (_parchment2.default.query(name, _parchment2.default.Scope.INLINE) != null) { - _this3.quill.format(name, false); - } - }); - } else { - this.quill.removeFormat(range, _quill2.default.sources.USER); - } - }, - direction: function direction(value) { - var align = this.quill.getFormat()['align']; - if (value === 'rtl' && align == null) { - this.quill.format('align', 'right', _quill2.default.sources.USER); - } else if (!value && align === 'right') { - this.quill.format('align', false, _quill2.default.sources.USER); - } - this.quill.format('direction', value, _quill2.default.sources.USER); - }, - indent: function indent(value) { - var range = this.quill.getSelection(); - var formats = this.quill.getFormat(range); - var indent = parseInt(formats.indent || 0); - if (value === '+1' || value === '-1') { - var modifier = value === '+1' ? 1 : -1; - if (formats.direction === 'rtl') modifier *= -1; - this.quill.format('indent', indent + modifier, _quill2.default.sources.USER); - } - }, - link: function link(value) { - if (value === true) { - value = prompt('Enter link URL:'); - } - this.quill.format('link', value, _quill2.default.sources.USER); - }, - list: function list(value) { - var range = this.quill.getSelection(); - var formats = this.quill.getFormat(range); - if (value === 'check') { - if (formats['list'] === 'checked' || formats['list'] === 'unchecked') { - this.quill.format('list', false, _quill2.default.sources.USER); - } else { - this.quill.format('list', 'unchecked', _quill2.default.sources.USER); - } - } else { - this.quill.format('list', value, _quill2.default.sources.USER); - } - } - } -}; - -exports.default = Toolbar; -exports.addControls = addControls; - -/***/ }), -/* 58 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 59 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _picker = __webpack_require__(28); - -var _picker2 = _interopRequireDefault(_picker); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var ColorPicker = function (_Picker) { - _inherits(ColorPicker, _Picker); - - function ColorPicker(select, label) { - _classCallCheck(this, ColorPicker); - - var _this = _possibleConstructorReturn(this, (ColorPicker.__proto__ || Object.getPrototypeOf(ColorPicker)).call(this, select)); - - _this.label.innerHTML = label; - _this.container.classList.add('ql-color-picker'); - [].slice.call(_this.container.querySelectorAll('.ql-picker-item'), 0, 7).forEach(function (item) { - item.classList.add('ql-primary'); - }); - return _this; - } - - _createClass(ColorPicker, [{ - key: 'buildItem', - value: function buildItem(option) { - var item = _get(ColorPicker.prototype.__proto__ || Object.getPrototypeOf(ColorPicker.prototype), 'buildItem', this).call(this, option); - item.style.backgroundColor = option.getAttribute('value') || ''; - return item; - } - }, { - key: 'selectItem', - value: function selectItem(item, trigger) { - _get(ColorPicker.prototype.__proto__ || Object.getPrototypeOf(ColorPicker.prototype), 'selectItem', this).call(this, item, trigger); - var colorLabel = this.label.querySelector('.ql-color-label'); - var value = item ? item.getAttribute('data-value') || '' : ''; - if (colorLabel) { - if (colorLabel.tagName === 'line') { - colorLabel.style.stroke = value; - } else { - colorLabel.style.fill = value; - } - } - } - }]); - - return ColorPicker; -}(_picker2.default); - -exports.default = ColorPicker; - -/***/ }), -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _picker = __webpack_require__(28); - -var _picker2 = _interopRequireDefault(_picker); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var IconPicker = function (_Picker) { - _inherits(IconPicker, _Picker); - - function IconPicker(select, icons) { - _classCallCheck(this, IconPicker); - - var _this = _possibleConstructorReturn(this, (IconPicker.__proto__ || Object.getPrototypeOf(IconPicker)).call(this, select)); - - _this.container.classList.add('ql-icon-picker'); - [].forEach.call(_this.container.querySelectorAll('.ql-picker-item'), function (item) { - item.innerHTML = icons[item.getAttribute('data-value') || '']; - }); - _this.defaultItem = _this.container.querySelector('.ql-selected'); - _this.selectItem(_this.defaultItem); - return _this; - } - - _createClass(IconPicker, [{ - key: 'selectItem', - value: function selectItem(item, trigger) { - _get(IconPicker.prototype.__proto__ || Object.getPrototypeOf(IconPicker.prototype), 'selectItem', this).call(this, item, trigger); - item = item || this.defaultItem; - this.label.innerHTML = item.innerHTML; - } - }]); - - return IconPicker; -}(_picker2.default); - -exports.default = IconPicker; - -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Tooltip = function () { - function Tooltip(quill, boundsContainer) { - var _this = this; - - _classCallCheck(this, Tooltip); - - this.quill = quill; - this.boundsContainer = boundsContainer || document.body; - this.root = quill.addContainer('ql-tooltip'); - this.root.innerHTML = this.constructor.TEMPLATE; - if (this.quill.root === this.quill.scrollingContainer) { - this.quill.root.addEventListener('scroll', function () { - _this.root.style.marginTop = -1 * _this.quill.root.scrollTop + 'px'; - }); - } - this.hide(); - } - - _createClass(Tooltip, [{ - key: 'hide', - value: function hide() { - this.root.classList.add('ql-hidden'); - } - }, { - key: 'position', - value: function position(reference) { - var left = reference.left + reference.width / 2 - this.root.offsetWidth / 2; - // root.scrollTop should be 0 if scrollContainer !== root - var top = reference.bottom + this.quill.root.scrollTop; - this.root.style.left = left + 'px'; - this.root.style.top = top + 'px'; - this.root.classList.remove('ql-flip'); - var containerBounds = this.boundsContainer.getBoundingClientRect(); - var rootBounds = this.root.getBoundingClientRect(); - var shift = 0; - if (rootBounds.right > containerBounds.right) { - shift = containerBounds.right - rootBounds.right; - this.root.style.left = left + shift + 'px'; - } - if (rootBounds.left < containerBounds.left) { - shift = containerBounds.left - rootBounds.left; - this.root.style.left = left + shift + 'px'; - } - if (rootBounds.bottom > containerBounds.bottom) { - var height = rootBounds.bottom - rootBounds.top; - var verticalShift = reference.bottom - reference.top + height; - this.root.style.top = top - verticalShift + 'px'; - this.root.classList.add('ql-flip'); - } - return shift; - } - }, { - key: 'show', - value: function show() { - this.root.classList.remove('ql-editing'); - this.root.classList.remove('ql-hidden'); - } - }]); - - return Tooltip; -}(); - -exports.default = Tooltip; - -/***/ }), -/* 62 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _extend = __webpack_require__(3); - -var _extend2 = _interopRequireDefault(_extend); - -var _emitter = __webpack_require__(8); - -var _emitter2 = _interopRequireDefault(_emitter); - -var _base = __webpack_require__(43); - -var _base2 = _interopRequireDefault(_base); - -var _link = __webpack_require__(27); - -var _link2 = _interopRequireDefault(_link); - -var _selection = __webpack_require__(15); - -var _icons = __webpack_require__(41); - -var _icons2 = _interopRequireDefault(_icons); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var TOOLBAR_CONFIG = [[{ header: ['1', '2', '3', false] }], ['bold', 'italic', 'underline', 'link'], [{ list: 'ordered' }, { list: 'bullet' }], ['clean']]; - -var SnowTheme = function (_BaseTheme) { - _inherits(SnowTheme, _BaseTheme); - - function SnowTheme(quill, options) { - _classCallCheck(this, SnowTheme); - - if (options.modules.toolbar != null && options.modules.toolbar.container == null) { - options.modules.toolbar.container = TOOLBAR_CONFIG; - } - - var _this = _possibleConstructorReturn(this, (SnowTheme.__proto__ || Object.getPrototypeOf(SnowTheme)).call(this, quill, options)); - - _this.quill.container.classList.add('ql-snow'); - return _this; - } - - _createClass(SnowTheme, [{ - key: 'extendToolbar', - value: function extendToolbar(toolbar) { - toolbar.container.classList.add('ql-snow'); - this.buildButtons([].slice.call(toolbar.container.querySelectorAll('button')), _icons2.default); - this.buildPickers([].slice.call(toolbar.container.querySelectorAll('select')), _icons2.default); - this.tooltip = new SnowTooltip(this.quill, this.options.bounds); - if (toolbar.container.querySelector('.ql-link')) { - this.quill.keyboard.addBinding({ key: 'K', shortKey: true }, function (range, context) { - toolbar.handlers['link'].call(toolbar, !context.format.link); - }); - } - } - }]); - - return SnowTheme; -}(_base2.default); - -SnowTheme.DEFAULTS = (0, _extend2.default)(true, {}, _base2.default.DEFAULTS, { - modules: { - toolbar: { - handlers: { - link: function link(value) { - if (value) { - var range = this.quill.getSelection(); - if (range == null || range.length == 0) return; - var preview = this.quill.getText(range); - if (/^\S+@\S+\.\S+$/.test(preview) && preview.indexOf('mailto:') !== 0) { - preview = 'mailto:' + preview; - } - var tooltip = this.quill.theme.tooltip; - tooltip.edit('link', preview); - } else { - this.quill.format('link', false); - } - } - } - } - } -}); - -var SnowTooltip = function (_BaseTooltip) { - _inherits(SnowTooltip, _BaseTooltip); - - function SnowTooltip(quill, bounds) { - _classCallCheck(this, SnowTooltip); - - var _this2 = _possibleConstructorReturn(this, (SnowTooltip.__proto__ || Object.getPrototypeOf(SnowTooltip)).call(this, quill, bounds)); - - _this2.preview = _this2.root.querySelector('a'); - return _this2; - } - - _createClass(SnowTooltip, [{ - key: 'listen', - value: function listen() { - var _this3 = this; - - _get(SnowTooltip.prototype.__proto__ || Object.getPrototypeOf(SnowTooltip.prototype), 'listen', this).call(this); - this.root.querySelector('a.ql-action').addEventListener('click', function (event) { - if (_this3.root.classList.contains('ql-editing')) { - _this3.save(); - } else { - _this3.edit('link', _this3.preview.textContent); - } - event.preventDefault(); - }); - this.root.querySelector('a.ql-remove').addEventListener('click', function (event) { - if (_this3.linkRange != null) { - var range = _this3.linkRange; - _this3.restoreFocus(); - _this3.quill.formatText(range, 'link', false, _emitter2.default.sources.USER); - delete _this3.linkRange; - } - event.preventDefault(); - _this3.hide(); - }); - this.quill.on(_emitter2.default.events.SELECTION_CHANGE, function (range, oldRange, source) { - if (range == null) return; - if (range.length === 0 && source === _emitter2.default.sources.USER) { - var _quill$scroll$descend = _this3.quill.scroll.descendant(_link2.default, range.index), - _quill$scroll$descend2 = _slicedToArray(_quill$scroll$descend, 2), - link = _quill$scroll$descend2[0], - offset = _quill$scroll$descend2[1]; - - if (link != null) { - _this3.linkRange = new _selection.Range(range.index - offset, link.length()); - var preview = _link2.default.formats(link.domNode); - _this3.preview.textContent = preview; - _this3.preview.setAttribute('href', preview); - _this3.show(); - _this3.position(_this3.quill.getBounds(_this3.linkRange)); - return; - } - } else { - delete _this3.linkRange; - } - _this3.hide(); - }); - } - }, { - key: 'show', - value: function show() { - _get(SnowTooltip.prototype.__proto__ || Object.getPrototypeOf(SnowTooltip.prototype), 'show', this).call(this); - this.root.removeAttribute('data-mode'); - } - }]); - - return SnowTooltip; -}(_base.BaseTooltip); - -SnowTooltip.TEMPLATE = ['', '', '', ''].join(''); - -exports.default = SnowTheme; - -/***/ }), -/* 63 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _core = __webpack_require__(29); - -var _core2 = _interopRequireDefault(_core); - -var _align = __webpack_require__(36); - -var _direction = __webpack_require__(38); - -var _indent = __webpack_require__(64); - -var _blockquote = __webpack_require__(65); - -var _blockquote2 = _interopRequireDefault(_blockquote); - -var _header = __webpack_require__(66); - -var _header2 = _interopRequireDefault(_header); - -var _list = __webpack_require__(67); - -var _list2 = _interopRequireDefault(_list); - -var _background = __webpack_require__(37); - -var _color = __webpack_require__(26); - -var _font = __webpack_require__(39); - -var _size = __webpack_require__(40); - -var _bold = __webpack_require__(56); - -var _bold2 = _interopRequireDefault(_bold); - -var _italic = __webpack_require__(68); - -var _italic2 = _interopRequireDefault(_italic); - -var _link = __webpack_require__(27); - -var _link2 = _interopRequireDefault(_link); - -var _script = __webpack_require__(69); - -var _script2 = _interopRequireDefault(_script); - -var _strike = __webpack_require__(70); - -var _strike2 = _interopRequireDefault(_strike); - -var _underline = __webpack_require__(71); - -var _underline2 = _interopRequireDefault(_underline); - -var _image = __webpack_require__(72); - -var _image2 = _interopRequireDefault(_image); - -var _video = __webpack_require__(73); - -var _video2 = _interopRequireDefault(_video); - -var _code = __webpack_require__(13); - -var _code2 = _interopRequireDefault(_code); - -var _formula = __webpack_require__(74); - -var _formula2 = _interopRequireDefault(_formula); - -var _syntax = __webpack_require__(75); - -var _syntax2 = _interopRequireDefault(_syntax); - -var _toolbar = __webpack_require__(57); - -var _toolbar2 = _interopRequireDefault(_toolbar); - -var _icons = __webpack_require__(41); - -var _icons2 = _interopRequireDefault(_icons); - -var _picker = __webpack_require__(28); - -var _picker2 = _interopRequireDefault(_picker); - -var _colorPicker = __webpack_require__(59); - -var _colorPicker2 = _interopRequireDefault(_colorPicker); - -var _iconPicker = __webpack_require__(60); - -var _iconPicker2 = _interopRequireDefault(_iconPicker); - -var _tooltip = __webpack_require__(61); - -var _tooltip2 = _interopRequireDefault(_tooltip); - -var _bubble = __webpack_require__(108); - -var _bubble2 = _interopRequireDefault(_bubble); - -var _snow = __webpack_require__(62); - -var _snow2 = _interopRequireDefault(_snow); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -_core2.default.register({ - 'attributors/attribute/direction': _direction.DirectionAttribute, - - 'attributors/class/align': _align.AlignClass, - 'attributors/class/background': _background.BackgroundClass, - 'attributors/class/color': _color.ColorClass, - 'attributors/class/direction': _direction.DirectionClass, - 'attributors/class/font': _font.FontClass, - 'attributors/class/size': _size.SizeClass, - - 'attributors/style/align': _align.AlignStyle, - 'attributors/style/background': _background.BackgroundStyle, - 'attributors/style/color': _color.ColorStyle, - 'attributors/style/direction': _direction.DirectionStyle, - 'attributors/style/font': _font.FontStyle, - 'attributors/style/size': _size.SizeStyle -}, true); - -_core2.default.register({ - 'formats/align': _align.AlignClass, - 'formats/direction': _direction.DirectionClass, - 'formats/indent': _indent.IndentClass, - - 'formats/background': _background.BackgroundStyle, - 'formats/color': _color.ColorStyle, - 'formats/font': _font.FontClass, - 'formats/size': _size.SizeClass, - - 'formats/blockquote': _blockquote2.default, - 'formats/code-block': _code2.default, - 'formats/header': _header2.default, - 'formats/list': _list2.default, - - 'formats/bold': _bold2.default, - 'formats/code': _code.Code, - 'formats/italic': _italic2.default, - 'formats/link': _link2.default, - 'formats/script': _script2.default, - 'formats/strike': _strike2.default, - 'formats/underline': _underline2.default, - - 'formats/image': _image2.default, - 'formats/video': _video2.default, - - 'formats/list/item': _list.ListItem, - - 'modules/formula': _formula2.default, - 'modules/syntax': _syntax2.default, - 'modules/toolbar': _toolbar2.default, - - 'themes/bubble': _bubble2.default, - 'themes/snow': _snow2.default, - - 'ui/icons': _icons2.default, - 'ui/picker': _picker2.default, - 'ui/icon-picker': _iconPicker2.default, - 'ui/color-picker': _colorPicker2.default, - 'ui/tooltip': _tooltip2.default -}, true); - -exports.default = _core2.default; - -/***/ }), -/* 64 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.IndentClass = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var IdentAttributor = function (_Parchment$Attributor) { - _inherits(IdentAttributor, _Parchment$Attributor); - - function IdentAttributor() { - _classCallCheck(this, IdentAttributor); - - return _possibleConstructorReturn(this, (IdentAttributor.__proto__ || Object.getPrototypeOf(IdentAttributor)).apply(this, arguments)); - } - - _createClass(IdentAttributor, [{ - key: 'add', - value: function add(node, value) { - if (value === '+1' || value === '-1') { - var indent = this.value(node) || 0; - value = value === '+1' ? indent + 1 : indent - 1; - } - if (value === 0) { - this.remove(node); - return true; - } else { - return _get(IdentAttributor.prototype.__proto__ || Object.getPrototypeOf(IdentAttributor.prototype), 'add', this).call(this, node, value); - } - } - }, { - key: 'canAdd', - value: function canAdd(node, value) { - return _get(IdentAttributor.prototype.__proto__ || Object.getPrototypeOf(IdentAttributor.prototype), 'canAdd', this).call(this, node, value) || _get(IdentAttributor.prototype.__proto__ || Object.getPrototypeOf(IdentAttributor.prototype), 'canAdd', this).call(this, node, parseInt(value)); - } - }, { - key: 'value', - value: function value(node) { - return parseInt(_get(IdentAttributor.prototype.__proto__ || Object.getPrototypeOf(IdentAttributor.prototype), 'value', this).call(this, node)) || undefined; // Don't return NaN - } - }]); - - return IdentAttributor; -}(_parchment2.default.Attributor.Class); - -var IndentClass = new IdentAttributor('indent', 'ql-indent', { - scope: _parchment2.default.Scope.BLOCK, - whitelist: [1, 2, 3, 4, 5, 6, 7, 8] -}); - -exports.IndentClass = IndentClass; - -/***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _block = __webpack_require__(4); - -var _block2 = _interopRequireDefault(_block); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Blockquote = function (_Block) { - _inherits(Blockquote, _Block); - - function Blockquote() { - _classCallCheck(this, Blockquote); - - return _possibleConstructorReturn(this, (Blockquote.__proto__ || Object.getPrototypeOf(Blockquote)).apply(this, arguments)); - } - - return Blockquote; -}(_block2.default); - -Blockquote.blotName = 'blockquote'; -Blockquote.tagName = 'blockquote'; - -exports.default = Blockquote; - -/***/ }), -/* 66 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _block = __webpack_require__(4); - -var _block2 = _interopRequireDefault(_block); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Header = function (_Block) { - _inherits(Header, _Block); - - function Header() { - _classCallCheck(this, Header); - - return _possibleConstructorReturn(this, (Header.__proto__ || Object.getPrototypeOf(Header)).apply(this, arguments)); - } - - _createClass(Header, null, [{ - key: 'formats', - value: function formats(domNode) { - return this.tagName.indexOf(domNode.tagName) + 1; - } - }]); - - return Header; -}(_block2.default); - -Header.blotName = 'header'; -Header.tagName = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']; - -exports.default = Header; - -/***/ }), -/* 67 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.ListItem = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _block = __webpack_require__(4); - -var _block2 = _interopRequireDefault(_block); - -var _container = __webpack_require__(25); - -var _container2 = _interopRequireDefault(_container); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var ListItem = function (_Block) { - _inherits(ListItem, _Block); - - function ListItem() { - _classCallCheck(this, ListItem); - - return _possibleConstructorReturn(this, (ListItem.__proto__ || Object.getPrototypeOf(ListItem)).apply(this, arguments)); - } - - _createClass(ListItem, [{ - key: 'format', - value: function format(name, value) { - if (name === List.blotName && !value) { - this.replaceWith(_parchment2.default.create(this.statics.scope)); - } else { - _get(ListItem.prototype.__proto__ || Object.getPrototypeOf(ListItem.prototype), 'format', this).call(this, name, value); - } - } - }, { - key: 'remove', - value: function remove() { - if (this.prev == null && this.next == null) { - this.parent.remove(); - } else { - _get(ListItem.prototype.__proto__ || Object.getPrototypeOf(ListItem.prototype), 'remove', this).call(this); - } - } - }, { - key: 'replaceWith', - value: function replaceWith(name, value) { - this.parent.isolate(this.offset(this.parent), this.length()); - if (name === this.parent.statics.blotName) { - this.parent.replaceWith(name, value); - return this; - } else { - this.parent.unwrap(); - return _get(ListItem.prototype.__proto__ || Object.getPrototypeOf(ListItem.prototype), 'replaceWith', this).call(this, name, value); - } - } - }], [{ - key: 'formats', - value: function formats(domNode) { - return domNode.tagName === this.tagName ? undefined : _get(ListItem.__proto__ || Object.getPrototypeOf(ListItem), 'formats', this).call(this, domNode); - } - }]); - - return ListItem; -}(_block2.default); - -ListItem.blotName = 'list-item'; -ListItem.tagName = 'LI'; - -var List = function (_Container) { - _inherits(List, _Container); - - _createClass(List, null, [{ - key: 'create', - value: function create(value) { - var tagName = value === 'ordered' ? 'OL' : 'UL'; - var node = _get(List.__proto__ || Object.getPrototypeOf(List), 'create', this).call(this, tagName); - if (value === 'checked' || value === 'unchecked') { - node.setAttribute('data-checked', value === 'checked'); - } - return node; - } - }, { - key: 'formats', - value: function formats(domNode) { - if (domNode.tagName === 'OL') return 'ordered'; - if (domNode.tagName === 'UL') { - if (domNode.hasAttribute('data-checked')) { - return domNode.getAttribute('data-checked') === 'true' ? 'checked' : 'unchecked'; - } else { - return 'bullet'; - } - } - return undefined; - } - }]); - - function List(domNode) { - _classCallCheck(this, List); - - var _this2 = _possibleConstructorReturn(this, (List.__proto__ || Object.getPrototypeOf(List)).call(this, domNode)); - - var listEventHandler = function listEventHandler(e) { - if (e.target.parentNode !== domNode) return; - var format = _this2.statics.formats(domNode); - var blot = _parchment2.default.find(e.target); - if (format === 'checked') { - blot.format('list', 'unchecked'); - } else if (format === 'unchecked') { - blot.format('list', 'checked'); - } - }; - - domNode.addEventListener('touchstart', listEventHandler); - domNode.addEventListener('mousedown', listEventHandler); - return _this2; - } - - _createClass(List, [{ - key: 'format', - value: function format(name, value) { - if (this.children.length > 0) { - this.children.tail.format(name, value); - } - } - }, { - key: 'formats', - value: function formats() { - // We don't inherit from FormatBlot - return _defineProperty({}, this.statics.blotName, this.statics.formats(this.domNode)); - } - }, { - key: 'insertBefore', - value: function insertBefore(blot, ref) { - if (blot instanceof ListItem) { - _get(List.prototype.__proto__ || Object.getPrototypeOf(List.prototype), 'insertBefore', this).call(this, blot, ref); - } else { - var index = ref == null ? this.length() : ref.offset(this); - var after = this.split(index); - after.parent.insertBefore(blot, after); - } - } - }, { - key: 'optimize', - value: function optimize(context) { - _get(List.prototype.__proto__ || Object.getPrototypeOf(List.prototype), 'optimize', this).call(this, context); - var next = this.next; - if (next != null && next.prev === this && next.statics.blotName === this.statics.blotName && next.domNode.tagName === this.domNode.tagName && next.domNode.getAttribute('data-checked') === this.domNode.getAttribute('data-checked')) { - next.moveChildren(this); - next.remove(); - } - } - }, { - key: 'replace', - value: function replace(target) { - if (target.statics.blotName !== this.statics.blotName) { - var item = _parchment2.default.create(this.statics.defaultChild); - target.moveChildren(item); - this.appendChild(item); - } - _get(List.prototype.__proto__ || Object.getPrototypeOf(List.prototype), 'replace', this).call(this, target); - } - }]); - - return List; -}(_container2.default); - -List.blotName = 'list'; -List.scope = _parchment2.default.Scope.BLOCK_BLOT; -List.tagName = ['OL', 'UL']; -List.defaultChild = 'list-item'; -List.allowedChildren = [ListItem]; - -exports.ListItem = ListItem; -exports.default = List; - -/***/ }), -/* 68 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _bold = __webpack_require__(56); - -var _bold2 = _interopRequireDefault(_bold); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Italic = function (_Bold) { - _inherits(Italic, _Bold); - - function Italic() { - _classCallCheck(this, Italic); - - return _possibleConstructorReturn(this, (Italic.__proto__ || Object.getPrototypeOf(Italic)).apply(this, arguments)); - } - - return Italic; -}(_bold2.default); - -Italic.blotName = 'italic'; -Italic.tagName = ['EM', 'I']; - -exports.default = Italic; - -/***/ }), -/* 69 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _inline = __webpack_require__(6); - -var _inline2 = _interopRequireDefault(_inline); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Script = function (_Inline) { - _inherits(Script, _Inline); - - function Script() { - _classCallCheck(this, Script); - - return _possibleConstructorReturn(this, (Script.__proto__ || Object.getPrototypeOf(Script)).apply(this, arguments)); - } - - _createClass(Script, null, [{ - key: 'create', - value: function create(value) { - if (value === 'super') { - return document.createElement('sup'); - } else if (value === 'sub') { - return document.createElement('sub'); - } else { - return _get(Script.__proto__ || Object.getPrototypeOf(Script), 'create', this).call(this, value); - } - } - }, { - key: 'formats', - value: function formats(domNode) { - if (domNode.tagName === 'SUB') return 'sub'; - if (domNode.tagName === 'SUP') return 'super'; - return undefined; - } - }]); - - return Script; -}(_inline2.default); - -Script.blotName = 'script'; -Script.tagName = ['SUB', 'SUP']; - -exports.default = Script; - -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _inline = __webpack_require__(6); - -var _inline2 = _interopRequireDefault(_inline); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Strike = function (_Inline) { - _inherits(Strike, _Inline); - - function Strike() { - _classCallCheck(this, Strike); - - return _possibleConstructorReturn(this, (Strike.__proto__ || Object.getPrototypeOf(Strike)).apply(this, arguments)); - } - - return Strike; -}(_inline2.default); - -Strike.blotName = 'strike'; -Strike.tagName = 'S'; - -exports.default = Strike; - -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _inline = __webpack_require__(6); - -var _inline2 = _interopRequireDefault(_inline); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var Underline = function (_Inline) { - _inherits(Underline, _Inline); - - function Underline() { - _classCallCheck(this, Underline); - - return _possibleConstructorReturn(this, (Underline.__proto__ || Object.getPrototypeOf(Underline)).apply(this, arguments)); - } - - return Underline; -}(_inline2.default); - -Underline.blotName = 'underline'; -Underline.tagName = 'U'; - -exports.default = Underline; - -/***/ }), -/* 72 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _link = __webpack_require__(27); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var ATTRIBUTES = ['alt', 'height', 'width']; - -var Image = function (_Parchment$Embed) { - _inherits(Image, _Parchment$Embed); - - function Image() { - _classCallCheck(this, Image); - - return _possibleConstructorReturn(this, (Image.__proto__ || Object.getPrototypeOf(Image)).apply(this, arguments)); - } - - _createClass(Image, [{ - key: 'format', - value: function format(name, value) { - if (ATTRIBUTES.indexOf(name) > -1) { - if (value) { - this.domNode.setAttribute(name, value); - } else { - this.domNode.removeAttribute(name); - } - } else { - _get(Image.prototype.__proto__ || Object.getPrototypeOf(Image.prototype), 'format', this).call(this, name, value); - } - } - }], [{ - key: 'create', - value: function create(value) { - var node = _get(Image.__proto__ || Object.getPrototypeOf(Image), 'create', this).call(this, value); - if (typeof value === 'string') { - node.setAttribute('src', this.sanitize(value)); - } - return node; - } - }, { - key: 'formats', - value: function formats(domNode) { - return ATTRIBUTES.reduce(function (formats, attribute) { - if (domNode.hasAttribute(attribute)) { - formats[attribute] = domNode.getAttribute(attribute); - } - return formats; - }, {}); - } - }, { - key: 'match', - value: function match(url) { - return (/\.(jpe?g|gif|png)$/.test(url) || /^data:image\/.+;base64/.test(url) - ); - } - }, { - key: 'sanitize', - value: function sanitize(url) { - return (0, _link.sanitize)(url, ['http', 'https', 'data']) ? url : '//:0'; - } - }, { - key: 'value', - value: function value(domNode) { - return domNode.getAttribute('src'); - } - }]); - - return Image; -}(_parchment2.default.Embed); - -Image.blotName = 'image'; -Image.tagName = 'IMG'; - -exports.default = Image; - -/***/ }), -/* 73 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _block = __webpack_require__(4); - -var _link = __webpack_require__(27); - -var _link2 = _interopRequireDefault(_link); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var ATTRIBUTES = ['height', 'width']; - -var Video = function (_BlockEmbed) { - _inherits(Video, _BlockEmbed); - - function Video() { - _classCallCheck(this, Video); - - return _possibleConstructorReturn(this, (Video.__proto__ || Object.getPrototypeOf(Video)).apply(this, arguments)); - } - - _createClass(Video, [{ - key: 'format', - value: function format(name, value) { - if (ATTRIBUTES.indexOf(name) > -1) { - if (value) { - this.domNode.setAttribute(name, value); - } else { - this.domNode.removeAttribute(name); - } - } else { - _get(Video.prototype.__proto__ || Object.getPrototypeOf(Video.prototype), 'format', this).call(this, name, value); - } - } - }], [{ - key: 'create', - value: function create(value) { - var node = _get(Video.__proto__ || Object.getPrototypeOf(Video), 'create', this).call(this, value); - node.setAttribute('frameborder', '0'); - node.setAttribute('allowfullscreen', true); - node.setAttribute('src', this.sanitize(value)); - return node; - } - }, { - key: 'formats', - value: function formats(domNode) { - return ATTRIBUTES.reduce(function (formats, attribute) { - if (domNode.hasAttribute(attribute)) { - formats[attribute] = domNode.getAttribute(attribute); - } - return formats; - }, {}); - } - }, { - key: 'sanitize', - value: function sanitize(url) { - return _link2.default.sanitize(url); - } - }, { - key: 'value', - value: function value(domNode) { - return domNode.getAttribute('src'); - } - }]); - - return Video; -}(_block.BlockEmbed); - -Video.blotName = 'video'; -Video.className = 'ql-video'; -Video.tagName = 'IFRAME'; - -exports.default = Video; - -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.FormulaBlot = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _embed = __webpack_require__(35); - -var _embed2 = _interopRequireDefault(_embed); - -var _quill = __webpack_require__(5); - -var _quill2 = _interopRequireDefault(_quill); - -var _module = __webpack_require__(9); - -var _module2 = _interopRequireDefault(_module); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var FormulaBlot = function (_Embed) { - _inherits(FormulaBlot, _Embed); - - function FormulaBlot() { - _classCallCheck(this, FormulaBlot); - - return _possibleConstructorReturn(this, (FormulaBlot.__proto__ || Object.getPrototypeOf(FormulaBlot)).apply(this, arguments)); - } - - _createClass(FormulaBlot, null, [{ - key: 'create', - value: function create(value) { - var node = _get(FormulaBlot.__proto__ || Object.getPrototypeOf(FormulaBlot), 'create', this).call(this, value); - if (typeof value === 'string') { - window.katex.render(value, node, { - throwOnError: false, - errorColor: '#f00' - }); - node.setAttribute('data-value', value); - } - return node; - } - }, { - key: 'value', - value: function value(domNode) { - return domNode.getAttribute('data-value'); - } - }]); - - return FormulaBlot; -}(_embed2.default); - -FormulaBlot.blotName = 'formula'; -FormulaBlot.className = 'ql-formula'; -FormulaBlot.tagName = 'SPAN'; - -var Formula = function (_Module) { - _inherits(Formula, _Module); - - _createClass(Formula, null, [{ - key: 'register', - value: function register() { - _quill2.default.register(FormulaBlot, true); - } - }]); - - function Formula() { - _classCallCheck(this, Formula); - - var _this2 = _possibleConstructorReturn(this, (Formula.__proto__ || Object.getPrototypeOf(Formula)).call(this)); - - if (window.katex == null) { - throw new Error('Formula module requires KaTeX.'); - } - return _this2; - } - - return Formula; -}(_module2.default); - -exports.FormulaBlot = FormulaBlot; -exports.default = Formula; - -/***/ }), -/* 75 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.CodeToken = exports.CodeBlock = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _parchment = __webpack_require__(0); - -var _parchment2 = _interopRequireDefault(_parchment); - -var _quill = __webpack_require__(5); - -var _quill2 = _interopRequireDefault(_quill); - -var _module = __webpack_require__(9); - -var _module2 = _interopRequireDefault(_module); - -var _code = __webpack_require__(13); - -var _code2 = _interopRequireDefault(_code); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var SyntaxCodeBlock = function (_CodeBlock) { - _inherits(SyntaxCodeBlock, _CodeBlock); - - function SyntaxCodeBlock() { - _classCallCheck(this, SyntaxCodeBlock); - - return _possibleConstructorReturn(this, (SyntaxCodeBlock.__proto__ || Object.getPrototypeOf(SyntaxCodeBlock)).apply(this, arguments)); - } - - _createClass(SyntaxCodeBlock, [{ - key: 'replaceWith', - value: function replaceWith(block) { - this.domNode.textContent = this.domNode.textContent; - this.attach(); - _get(SyntaxCodeBlock.prototype.__proto__ || Object.getPrototypeOf(SyntaxCodeBlock.prototype), 'replaceWith', this).call(this, block); - } - }, { - key: 'highlight', - value: function highlight(_highlight) { - var text = this.domNode.textContent; - if (this.cachedText !== text) { - if (text.trim().length > 0 || this.cachedText == null) { - this.domNode.innerHTML = _highlight(text); - this.domNode.normalize(); - this.attach(); - } - this.cachedText = text; - } - } - }]); - - return SyntaxCodeBlock; -}(_code2.default); - -SyntaxCodeBlock.className = 'ql-syntax'; - -var CodeToken = new _parchment2.default.Attributor.Class('token', 'hljs', { - scope: _parchment2.default.Scope.INLINE -}); - -var Syntax = function (_Module) { - _inherits(Syntax, _Module); - - _createClass(Syntax, null, [{ - key: 'register', - value: function register() { - _quill2.default.register(CodeToken, true); - _quill2.default.register(SyntaxCodeBlock, true); - } - }]); - - function Syntax(quill, options) { - _classCallCheck(this, Syntax); - - var _this2 = _possibleConstructorReturn(this, (Syntax.__proto__ || Object.getPrototypeOf(Syntax)).call(this, quill, options)); - - if (typeof _this2.options.highlight !== 'function') { - throw new Error('Syntax module requires highlight.js. Please include the library on the page before Quill.'); - } - var timer = null; - _this2.quill.on(_quill2.default.events.SCROLL_OPTIMIZE, function () { - clearTimeout(timer); - timer = setTimeout(function () { - _this2.highlight(); - timer = null; - }, _this2.options.interval); - }); - _this2.highlight(); - return _this2; - } - - _createClass(Syntax, [{ - key: 'highlight', - value: function highlight() { - var _this3 = this; - - if (this.quill.selection.composing) return; - this.quill.update(_quill2.default.sources.USER); - var range = this.quill.getSelection(); - this.quill.scroll.descendants(SyntaxCodeBlock).forEach(function (code) { - code.highlight(_this3.options.highlight); - }); - this.quill.update(_quill2.default.sources.SILENT); - if (range != null) { - this.quill.setSelection(range, _quill2.default.sources.SILENT); - } - } - }]); - - return Syntax; -}(_module2.default); - -Syntax.DEFAULTS = { - highlight: function () { - if (window.hljs == null) return null; - return function (text) { - var result = window.hljs.highlightAuto(text); - return result.value; - }; - }(), - interval: 1000 -}; - -exports.CodeBlock = SyntaxCodeBlock; -exports.CodeToken = CodeToken; -exports.default = Syntax; - -/***/ }), -/* 76 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 77 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 78 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 79 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 80 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 81 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 82 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 83 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 84 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 85 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 86 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 87 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 88 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 89 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 90 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 91 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 92 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 93 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 94 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 95 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 96 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 97 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 98 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 99 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 100 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 101 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 102 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 103 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 104 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 105 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 106 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 107 */ -/***/ (function(module, exports) { - -module.exports = " "; - -/***/ }), -/* 108 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.BubbleTooltip = undefined; - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _extend = __webpack_require__(3); - -var _extend2 = _interopRequireDefault(_extend); - -var _emitter = __webpack_require__(8); - -var _emitter2 = _interopRequireDefault(_emitter); - -var _base = __webpack_require__(43); - -var _base2 = _interopRequireDefault(_base); - -var _selection = __webpack_require__(15); - -var _icons = __webpack_require__(41); - -var _icons2 = _interopRequireDefault(_icons); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var TOOLBAR_CONFIG = [['bold', 'italic', 'link'], [{ header: 1 }, { header: 2 }, 'blockquote']]; - -var BubbleTheme = function (_BaseTheme) { - _inherits(BubbleTheme, _BaseTheme); - - function BubbleTheme(quill, options) { - _classCallCheck(this, BubbleTheme); - - if (options.modules.toolbar != null && options.modules.toolbar.container == null) { - options.modules.toolbar.container = TOOLBAR_CONFIG; - } - - var _this = _possibleConstructorReturn(this, (BubbleTheme.__proto__ || Object.getPrototypeOf(BubbleTheme)).call(this, quill, options)); - - _this.quill.container.classList.add('ql-bubble'); - return _this; - } - - _createClass(BubbleTheme, [{ - key: 'extendToolbar', - value: function extendToolbar(toolbar) { - this.tooltip = new BubbleTooltip(this.quill, this.options.bounds); - this.tooltip.root.appendChild(toolbar.container); - this.buildButtons([].slice.call(toolbar.container.querySelectorAll('button')), _icons2.default); - this.buildPickers([].slice.call(toolbar.container.querySelectorAll('select')), _icons2.default); - } - }]); - - return BubbleTheme; -}(_base2.default); - -BubbleTheme.DEFAULTS = (0, _extend2.default)(true, {}, _base2.default.DEFAULTS, { - modules: { - toolbar: { - handlers: { - link: function link(value) { - if (!value) { - this.quill.format('link', false); - } else { - this.quill.theme.tooltip.edit(); - } - } - } - } - } -}); - -var BubbleTooltip = function (_BaseTooltip) { - _inherits(BubbleTooltip, _BaseTooltip); - - function BubbleTooltip(quill, bounds) { - _classCallCheck(this, BubbleTooltip); - - var _this2 = _possibleConstructorReturn(this, (BubbleTooltip.__proto__ || Object.getPrototypeOf(BubbleTooltip)).call(this, quill, bounds)); - - _this2.quill.on(_emitter2.default.events.EDITOR_CHANGE, function (type, range, oldRange, source) { - if (type !== _emitter2.default.events.SELECTION_CHANGE) return; - if (range != null && range.length > 0 && source === _emitter2.default.sources.USER) { - _this2.show(); - // Lock our width so we will expand beyond our offsetParent boundaries - _this2.root.style.left = '0px'; - _this2.root.style.width = ''; - _this2.root.style.width = _this2.root.offsetWidth + 'px'; - var lines = _this2.quill.getLines(range.index, range.length); - if (lines.length === 1) { - _this2.position(_this2.quill.getBounds(range)); - } else { - var lastLine = lines[lines.length - 1]; - var index = _this2.quill.getIndex(lastLine); - var length = Math.min(lastLine.length() - 1, range.index + range.length - index); - var _bounds = _this2.quill.getBounds(new _selection.Range(index, length)); - _this2.position(_bounds); - } - } else if (document.activeElement !== _this2.textbox && _this2.quill.hasFocus()) { - _this2.hide(); - } - }); - return _this2; - } - - _createClass(BubbleTooltip, [{ - key: 'listen', - value: function listen() { - var _this3 = this; - - _get(BubbleTooltip.prototype.__proto__ || Object.getPrototypeOf(BubbleTooltip.prototype), 'listen', this).call(this); - this.root.querySelector('.ql-close').addEventListener('click', function () { - _this3.root.classList.remove('ql-editing'); - }); - this.quill.on(_emitter2.default.events.SCROLL_OPTIMIZE, function () { - // Let selection be restored by toolbar handlers before repositioning - setTimeout(function () { - if (_this3.root.classList.contains('ql-hidden')) return; - var range = _this3.quill.getSelection(); - if (range != null) { - _this3.position(_this3.quill.getBounds(range)); - } - }, 1); - }); - } - }, { - key: 'cancel', - value: function cancel() { - this.show(); - } - }, { - key: 'position', - value: function position(reference) { - var shift = _get(BubbleTooltip.prototype.__proto__ || Object.getPrototypeOf(BubbleTooltip.prototype), 'position', this).call(this, reference); - var arrow = this.root.querySelector('.ql-tooltip-arrow'); - arrow.style.marginLeft = ''; - if (shift === 0) return shift; - arrow.style.marginLeft = -1 * shift - arrow.offsetWidth / 2 + 'px'; - } - }]); - - return BubbleTooltip; -}(_base.BaseTooltip); - -BubbleTooltip.TEMPLATE = ['', '
', '', '', '
'].join(''); - -exports.BubbleTooltip = BubbleTooltip; -exports.default = BubbleTheme; - -/***/ }), -/* 109 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(63); - - -/***/ }) -/******/ ])["default"]; -}); +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Quill=e():t.Quill=e()}(self,(function(){return function(){var t={9698:function(t,e,n){"use strict";n.d(e,{Ay:function(){return c},Ji:function(){return d},mG:function(){return h},zo:function(){return u}});var r=n(6003),i=n(5232),s=n.n(i),o=n(3036),l=n(4850),a=n(5508);class c extends r.BlockBlot{cache={};delta(){return null==this.cache.delta&&(this.cache.delta=h(this)),this.cache.delta}deleteAt(t,e){super.deleteAt(t,e),this.cache={}}formatAt(t,e,n,i){e<=0||(this.scroll.query(n,r.Scope.BLOCK)?t+e===this.length()&&this.format(n,i):super.formatAt(t,Math.min(e,this.length()-t-1),n,i),this.cache={})}insertAt(t,e,n){if(null!=n)return super.insertAt(t,e,n),void(this.cache={});if(0===e.length)return;const r=e.split("\n"),i=r.shift();i.length>0&&(t(s=s.split(t,!0),s.insertAt(0,e),e.length)),t+i.length)}insertBefore(t,e){const{head:n}=this.children;super.insertBefore(t,e),n instanceof o.A&&n.remove(),this.cache={}}length(){return null==this.cache.length&&(this.cache.length=super.length()+1),this.cache.length}moveChildren(t,e){super.moveChildren(t,e),this.cache={}}optimize(t){super.optimize(t),this.cache={}}path(t){return super.path(t,!0)}removeChild(t){super.removeChild(t),this.cache={}}split(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(e&&(0===t||t>=this.length()-1)){const e=this.clone();return 0===t?(this.parent.insertBefore(e,this),this):(this.parent.insertBefore(e,this.next),e)}const n=super.split(t,e);return this.cache={},n}}c.blotName="block",c.tagName="P",c.defaultChild=o.A,c.allowedChildren=[o.A,l.A,r.EmbedBlot,a.A];class u extends r.EmbedBlot{attach(){super.attach(),this.attributes=new r.AttributorStore(this.domNode)}delta(){return(new(s())).insert(this.value(),{...this.formats(),...this.attributes.values()})}format(t,e){const n=this.scroll.query(t,r.Scope.BLOCK_ATTRIBUTE);null!=n&&this.attributes.attribute(n,e)}formatAt(t,e,n,r){this.format(n,r)}insertAt(t,e,n){if(null!=n)return void super.insertAt(t,e,n);const r=e.split("\n"),i=r.pop(),s=r.map((t=>{const e=this.scroll.create(c.blotName);return e.insertAt(0,t),e})),o=this.split(t);s.forEach((t=>{this.parent.insertBefore(t,o)})),i&&this.parent.insertBefore(this.scroll.create("text",i),o)}}function h(t){let e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return t.descendants(r.LeafBlot).reduce(((t,n)=>0===n.length()?t:t.insert(n.value(),d(n,{},e))),new(s())).insert("\n",d(t))}function d(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return null==t?e:("formats"in t&&"function"==typeof t.formats&&(e={...e,...t.formats()},n&&delete e["code-token"]),null==t.parent||"scroll"===t.parent.statics.blotName||t.parent.statics.scope!==t.statics.scope?e:d(t.parent,e,n))}u.scope=r.Scope.BLOCK_BLOT},3036:function(t,e,n){"use strict";var r=n(6003);class i extends r.EmbedBlot{static value(){}optimize(){(this.prev||this.next)&&this.remove()}length(){return 0}value(){return""}}i.blotName="break",i.tagName="BR",e.A=i},580:function(t,e,n){"use strict";var r=n(6003);class i extends r.ContainerBlot{}e.A=i},4541:function(t,e,n){"use strict";var r=n(6003),i=n(5508);class s extends r.EmbedBlot{static blotName="cursor";static className="ql-cursor";static tagName="span";static CONTENTS="\ufeff";static value(){}constructor(t,e,n){super(t,e),this.selection=n,this.textNode=document.createTextNode(s.CONTENTS),this.domNode.appendChild(this.textNode),this.savedLength=0}detach(){null!=this.parent&&this.parent.removeChild(this)}format(t,e){if(0!==this.savedLength)return void super.format(t,e);let n=this,i=0;for(;null!=n&&n.statics.scope!==r.Scope.BLOCK_BLOT;)i+=n.offset(n.parent),n=n.parent;null!=n&&(this.savedLength=s.CONTENTS.length,n.optimize(),n.formatAt(i,s.CONTENTS.length,t,e),this.savedLength=0)}index(t,e){return t===this.textNode?0:super.index(t,e)}length(){return this.savedLength}position(){return[this.textNode,this.textNode.data.length]}remove(){super.remove(),this.parent=null}restore(){if(this.selection.composing||null==this.parent)return null;const t=this.selection.getNativeRange();for(;null!=this.domNode.lastChild&&this.domNode.lastChild!==this.textNode;)this.domNode.parentNode.insertBefore(this.domNode.lastChild,this.domNode);const e=this.prev instanceof i.A?this.prev:null,n=e?e.length():0,r=this.next instanceof i.A?this.next:null,o=r?r.text:"",{textNode:l}=this,a=l.data.split(s.CONTENTS).join("");let c;if(l.data=s.CONTENTS,e)c=e,(a||r)&&(e.insertAt(e.length(),a+o),r&&r.remove());else if(r)c=r,r.insertAt(0,a);else{const t=document.createTextNode(a);c=this.scroll.create(t),this.parent.insertBefore(c,this)}if(this.remove(),t){const i=(t,i)=>e&&t===e.domNode?i:t===l?n+i-1:r&&t===r.domNode?n+a.length+i:null,s=i(t.start.node,t.start.offset),o=i(t.end.node,t.end.offset);if(null!==s&&null!==o)return{startNode:c.domNode,startOffset:s,endNode:c.domNode,endOffset:o}}return null}update(t,e){if(t.some((t=>"characterData"===t.type&&t.target===this.textNode))){const t=this.restore();t&&(e.range=t)}}optimize(t){super.optimize(t);let{parent:e}=this;for(;e;){if("A"===e.domNode.tagName){this.savedLength=s.CONTENTS.length,e.isolate(this.offset(e),this.length()).unwrap(),this.savedLength=0;break}e=e.parent}}value(){return""}}e.A=s},746:function(t,e,n){"use strict";var r=n(6003),i=n(5508);const s="\ufeff";class o extends r.EmbedBlot{constructor(t,e){super(t,e),this.contentNode=document.createElement("span"),this.contentNode.setAttribute("contenteditable","false"),Array.from(this.domNode.childNodes).forEach((t=>{this.contentNode.appendChild(t)})),this.leftGuard=document.createTextNode(s),this.rightGuard=document.createTextNode(s),this.domNode.appendChild(this.leftGuard),this.domNode.appendChild(this.contentNode),this.domNode.appendChild(this.rightGuard)}index(t,e){return t===this.leftGuard?0:t===this.rightGuard?1:super.index(t,e)}restore(t){let e,n=null;const r=t.data.split(s).join("");if(t===this.leftGuard)if(this.prev instanceof i.A){const t=this.prev.length();this.prev.insertAt(t,r),n={startNode:this.prev.domNode,startOffset:t+r.length}}else e=document.createTextNode(r),this.parent.insertBefore(this.scroll.create(e),this),n={startNode:e,startOffset:r.length};else t===this.rightGuard&&(this.next instanceof i.A?(this.next.insertAt(0,r),n={startNode:this.next.domNode,startOffset:r.length}):(e=document.createTextNode(r),this.parent.insertBefore(this.scroll.create(e),this.next),n={startNode:e,startOffset:r.length}));return t.data=s,n}update(t,e){t.forEach((t=>{if("characterData"===t.type&&(t.target===this.leftGuard||t.target===this.rightGuard)){const n=this.restore(t.target);n&&(e.range=n)}}))}}e.A=o},4850:function(t,e,n){"use strict";var r=n(6003),i=n(3036),s=n(5508);class o extends r.InlineBlot{static allowedChildren=[o,i.A,r.EmbedBlot,s.A];static order=["cursor","inline","link","underline","strike","italic","bold","script","code"];static compare(t,e){const n=o.order.indexOf(t),r=o.order.indexOf(e);return n>=0||r>=0?n-r:t===e?0:t0){const t=this.parent.isolate(this.offset(),this.length());this.moveChildren(t),t.wrap(this)}}}e.A=o},5508:function(t,e,n){"use strict";n.d(e,{A:function(){return i},X:function(){return s}});var r=n(6003);class i extends r.TextBlot{}function s(t){return t.replace(/[&<>"']/g,(t=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[t])))}},3729:function(t,e,n){"use strict";n.d(e,{default:function(){return R}});var r=n(6142),i=n(9698),s=n(3036),o=n(580),l=n(4541),a=n(746),c=n(4850),u=n(6003),h=n(5232),d=n.n(h),f=n(5374);function p(t){return t instanceof i.Ay||t instanceof i.zo}function g(t){return"function"==typeof t.updateContent}class m extends u.ScrollBlot{static blotName="scroll";static className="ql-editor";static tagName="DIV";static defaultChild=i.Ay;static allowedChildren=[i.Ay,i.zo,o.A];constructor(t,e,n){let{emitter:r}=n;super(t,e),this.emitter=r,this.batch=!1,this.optimize(),this.enable(),this.domNode.addEventListener("dragstart",(t=>this.handleDragStart(t)))}batchStart(){Array.isArray(this.batch)||(this.batch=[])}batchEnd(){if(!this.batch)return;const t=this.batch;this.batch=!1,this.update(t)}emitMount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_MOUNT,t)}emitUnmount(t){this.emitter.emit(f.A.events.SCROLL_BLOT_UNMOUNT,t)}emitEmbedUpdate(t,e){this.emitter.emit(f.A.events.SCROLL_EMBED_UPDATE,t,e)}deleteAt(t,e){const[n,r]=this.line(t),[o]=this.line(t+e);if(super.deleteAt(t,e),null!=o&&n!==o&&r>0){if(n instanceof i.zo||o instanceof i.zo)return void this.optimize();const t=o.children.head instanceof s.A?null:o.children.head;n.moveChildren(o,t),n.remove()}this.optimize()}enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.domNode.setAttribute("contenteditable",t?"true":"false")}formatAt(t,e,n,r){super.formatAt(t,e,n,r),this.optimize()}insertAt(t,e,n){if(t>=this.length())if(null==n||null==this.scroll.query(e,u.Scope.BLOCK)){const t=this.scroll.create(this.statics.defaultChild.blotName);this.appendChild(t),null==n&&e.endsWith("\n")?t.insertAt(0,e.slice(0,-1),n):t.insertAt(0,e,n)}else{const t=this.scroll.create(e,n);this.appendChild(t)}else super.insertAt(t,e,n);this.optimize()}insertBefore(t,e){if(t.statics.scope===u.Scope.INLINE_BLOT){const n=this.scroll.create(this.statics.defaultChild.blotName);n.appendChild(t),super.insertBefore(n,e)}else super.insertBefore(t,e)}insertContents(t,e){const n=this.deltaToRenderBlocks(e.concat((new(d())).insert("\n"))),r=n.pop();if(null==r)return;this.batchStart();const s=n.shift();if(s){const e="block"===s.type&&(0===s.delta.length()||!this.descendant(i.zo,t)[0]&&t{this.formatAt(o-1,1,t,a[t])})),t=o}let[o,l]=this.children.find(t);n.length&&(o&&(o=o.split(l),l=0),n.forEach((t=>{if("block"===t.type)b(this.createBlock(t.attributes,o||void 0),0,t.delta);else{const e=this.create(t.key,t.value);this.insertBefore(e,o||void 0),Object.keys(t.attributes).forEach((n=>{e.format(n,t.attributes[n])}))}}))),"block"===r.type&&r.delta.length()&&b(this,o?o.offset(o.scroll)+l:this.length(),r.delta),this.batchEnd(),this.optimize()}isEnabled(){return"true"===this.domNode.getAttribute("contenteditable")}leaf(t){const e=this.path(t).pop();if(!e)return[null,-1];const[n,r]=e;return n instanceof u.LeafBlot?[n,r]:[null,-1]}line(t){return t===this.length()?this.line(t-1):this.descendant(p,t)}lines(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Number.MAX_VALUE;const n=(t,e,r)=>{let i=[],s=r;return t.children.forEachAt(e,r,((t,e,r)=>{p(t)?i.push(t):t instanceof u.ContainerBlot&&(i=i.concat(n(t,e,s))),s-=r})),i};return n(this,t,e)}optimize(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.batch||(super.optimize(t,e),t.length>0&&this.emitter.emit(f.A.events.SCROLL_OPTIMIZE,t,e))}path(t){return super.path(t).slice(1)}remove(){}update(t){if(this.batch)return void(Array.isArray(t)&&(this.batch=this.batch.concat(t)));let e=f.A.sources.USER;"string"==typeof t&&(e=t),Array.isArray(t)||(t=this.observer.takeRecords()),(t=t.filter((t=>{let{target:e}=t;const n=this.find(e,!0);return n&&!g(n)}))).length>0&&this.emitter.emit(f.A.events.SCROLL_BEFORE_UPDATE,e,t),super.update(t.concat([])),t.length>0&&this.emitter.emit(f.A.events.SCROLL_UPDATE,e,t)}updateEmbedAt(t,e,n){const[r]=this.descendant((t=>t instanceof i.zo),t);r&&r.statics.blotName===e&&g(r)&&r.updateContent(n)}handleDragStart(t){t.preventDefault()}deltaToRenderBlocks(t){const e=[];let n=new(d());return t.forEach((t=>{const r=t?.insert;if(r)if("string"==typeof r){const i=r.split("\n");i.slice(0,-1).forEach((r=>{n.insert(r,t.attributes),e.push({type:"block",delta:n,attributes:t.attributes??{}}),n=new(d())}));const s=i[i.length-1];s&&n.insert(s,t.attributes)}else{const i=Object.keys(r)[0];if(!i)return;this.query(i,u.Scope.INLINE)?n.push(t):(n.length()&&e.push({type:"block",delta:n,attributes:{}}),n=new(d()),e.push({type:"blockEmbed",key:i,value:r[i],attributes:t.attributes??{}}))}})),n.length()&&e.push({type:"block",delta:n,attributes:{}}),e}createBlock(t,e){let n;const r={};Object.entries(t).forEach((t=>{let[e,i]=t;null!=this.query(e,u.Scope.BLOCK&u.Scope.BLOT)?n=e:r[e]=i}));const i=this.create(n||this.statics.defaultChild.blotName,n?t[n]:void 0);this.insertBefore(i,e||void 0);const s=i.length();return Object.entries(r).forEach((t=>{let[e,n]=t;i.formatAt(0,s,e,n)})),i}}function b(t,e,n){n.reduce(((e,n)=>{const r=h.Op.length(n);let s=n.attributes||{};if(null!=n.insert)if("string"==typeof n.insert){const r=n.insert;t.insertAt(e,r);const[o]=t.descendant(u.LeafBlot,e),l=(0,i.Ji)(o);s=h.AttributeMap.diff(l,s)||{}}else if("object"==typeof n.insert){const r=Object.keys(n.insert)[0];if(null==r)return e;if(t.insertAt(e,r,n.insert[r]),null!=t.scroll.query(r,u.Scope.INLINE)){const[n]=t.descendant(u.LeafBlot,e),r=(0,i.Ji)(n);s=h.AttributeMap.diff(r,s)||{}}}return Object.keys(s).forEach((n=>{t.formatAt(e,r,n,s[n])})),e+r}),e)}var y=m,v=n(5508),A=n(584),x=n(4266);class N extends x.A{static DEFAULTS={delay:1e3,maxStack:100,userOnly:!1};lastRecorded=0;ignoreChange=!1;stack={undo:[],redo:[]};currentRange=null;constructor(t,e){super(t,e),this.quill.on(r.Ay.events.EDITOR_CHANGE,((t,e,n,i)=>{t===r.Ay.events.SELECTION_CHANGE?e&&i!==r.Ay.sources.SILENT&&(this.currentRange=e):t===r.Ay.events.TEXT_CHANGE&&(this.ignoreChange||(this.options.userOnly&&i!==r.Ay.sources.USER?this.transform(e):this.record(e,n)),this.currentRange=w(this.currentRange,e))})),this.quill.keyboard.addBinding({key:"z",shortKey:!0},this.undo.bind(this)),this.quill.keyboard.addBinding({key:["z","Z"],shortKey:!0,shiftKey:!0},this.redo.bind(this)),/Win/i.test(navigator.platform)&&this.quill.keyboard.addBinding({key:"y",shortKey:!0},this.redo.bind(this)),this.quill.root.addEventListener("beforeinput",(t=>{"historyUndo"===t.inputType?(this.undo(),t.preventDefault()):"historyRedo"===t.inputType&&(this.redo(),t.preventDefault())}))}change(t,e){if(0===this.stack[t].length)return;const n=this.stack[t].pop();if(!n)return;const i=this.quill.getContents(),s=n.delta.invert(i);this.stack[e].push({delta:s,range:w(n.range,s)}),this.lastRecorded=0,this.ignoreChange=!0,this.quill.updateContents(n.delta,r.Ay.sources.USER),this.ignoreChange=!1,this.restoreSelection(n)}clear(){this.stack={undo:[],redo:[]}}cutoff(){this.lastRecorded=0}record(t,e){if(0===t.ops.length)return;this.stack.redo=[];let n=t.invert(e),r=this.currentRange;const i=Date.now();if(this.lastRecorded+this.options.delay>i&&this.stack.undo.length>0){const t=this.stack.undo.pop();t&&(n=n.compose(t.delta),r=t.range)}else this.lastRecorded=i;0!==n.length()&&(this.stack.undo.push({delta:n,range:r}),this.stack.undo.length>this.options.maxStack&&this.stack.undo.shift())}redo(){this.change("redo","undo")}transform(t){E(this.stack.undo,t),E(this.stack.redo,t)}undo(){this.change("undo","redo")}restoreSelection(t){if(t.range)this.quill.setSelection(t.range,r.Ay.sources.USER);else{const e=function(t,e){const n=e.reduce(((t,e)=>t+(e.delete||0)),0);let r=e.length()-n;return function(t,e){const n=e.ops[e.ops.length-1];return null!=n&&(null!=n.insert?"string"==typeof n.insert&&n.insert.endsWith("\n"):null!=n.attributes&&Object.keys(n.attributes).some((e=>null!=t.query(e,u.Scope.BLOCK))))}(t,e)&&(r-=1),r}(this.quill.scroll,t.delta);this.quill.setSelection(e,r.Ay.sources.USER)}}}function E(t,e){let n=e;for(let e=t.length-1;e>=0;e-=1){const r=t[e];t[e]={delta:n.transform(r.delta,!0),range:r.range&&w(r.range,n)},n=r.delta.transform(n),0===t[e].delta.length()&&t.splice(e,1)}}function w(t,e){if(!t)return t;const n=e.transformPosition(t.index);return{index:n,length:e.transformPosition(t.index+t.length)-n}}var q=n(8123);class k extends x.A{constructor(t,e){super(t,e),t.root.addEventListener("drop",(e=>{e.preventDefault();let n=null;if(document.caretRangeFromPoint)n=document.caretRangeFromPoint(e.clientX,e.clientY);else if(document.caretPositionFromPoint){const t=document.caretPositionFromPoint(e.clientX,e.clientY);n=document.createRange(),n.setStart(t.offsetNode,t.offset),n.setEnd(t.offsetNode,t.offset)}const r=n&&t.selection.normalizeNative(n);if(r){const n=t.selection.normalizedToRange(r);e.dataTransfer?.files&&this.upload(n,e.dataTransfer.files)}}))}upload(t,e){const n=[];Array.from(e).forEach((t=>{t&&this.options.mimetypes?.includes(t.type)&&n.push(t)})),n.length>0&&this.options.handler.call(this,t,n)}}k.DEFAULTS={mimetypes:["image/png","image/jpeg"],handler(t,e){if(!this.quill.scroll.query("image"))return;const n=e.map((t=>new Promise((e=>{const n=new FileReader;n.onload=()=>{e(n.result)},n.readAsDataURL(t)}))));Promise.all(n).then((e=>{const n=e.reduce(((t,e)=>t.insert({image:e})),(new(d())).retain(t.index).delete(t.length));this.quill.updateContents(n,f.A.sources.USER),this.quill.setSelection(t.index+e.length,f.A.sources.SILENT)}))}};var _=k;const L=["insertText","insertReplacementText"];class S extends x.A{constructor(t,e){super(t,e),t.root.addEventListener("beforeinput",(t=>{this.handleBeforeInput(t)})),/Android/i.test(navigator.userAgent)||t.on(r.Ay.events.COMPOSITION_BEFORE_START,(()=>{this.handleCompositionStart()}))}deleteRange(t){(0,q.Xo)({range:t,quill:this.quill})}replaceText(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(0===t.length)return!1;if(e){const n=this.quill.getFormat(t.index,1);this.deleteRange(t),this.quill.updateContents((new(d())).retain(t.index).insert(e,n),r.Ay.sources.USER)}else this.deleteRange(t);return this.quill.setSelection(t.index+e.length,0,r.Ay.sources.SILENT),!0}handleBeforeInput(t){if(this.quill.composition.isComposing||t.defaultPrevented||!L.includes(t.inputType))return;const e=t.getTargetRanges?t.getTargetRanges()[0]:null;if(!e||!0===e.collapsed)return;const n=function(t){return"string"==typeof t.data?t.data:t.dataTransfer?.types.includes("text/plain")?t.dataTransfer.getData("text/plain"):null}(t);if(null==n)return;const r=this.quill.selection.normalizeNative(e),i=r?this.quill.selection.normalizedToRange(r):null;i&&this.replaceText(i,n)&&t.preventDefault()}handleCompositionStart(){const t=this.quill.getSelection();t&&this.replaceText(t)}}var O=S;const T=/Mac/i.test(navigator.platform);class j extends x.A{isListening=!1;selectionChangeDeadline=0;constructor(t,e){super(t,e),this.handleArrowKeys(),this.handleNavigationShortcuts()}handleArrowKeys(){this.quill.keyboard.addBinding({key:["ArrowLeft","ArrowRight"],offset:0,shiftKey:null,handler(t,e){let{line:n,event:i}=e;if(!(n instanceof u.ParentBlot&&n.uiNode))return!0;const s="rtl"===getComputedStyle(n.domNode).direction;return!!(s&&"ArrowRight"!==i.key||!s&&"ArrowLeft"!==i.key)||(this.quill.setSelection(t.index-1,t.length+(i.shiftKey?1:0),r.Ay.sources.USER),!1)}})}handleNavigationShortcuts(){this.quill.root.addEventListener("keydown",(t=>{!t.defaultPrevented&&(t=>"ArrowLeft"===t.key||"ArrowRight"===t.key||"ArrowUp"===t.key||"ArrowDown"===t.key||"Home"===t.key||!(!T||"a"!==t.key||!0!==t.ctrlKey))(t)&&this.ensureListeningToSelectionChange()}))}ensureListeningToSelectionChange(){this.selectionChangeDeadline=Date.now()+100,this.isListening||(this.isListening=!0,document.addEventListener("selectionchange",(()=>{this.isListening=!1,Date.now()<=this.selectionChangeDeadline&&this.handleSelectionChange()}),{once:!0}))}handleSelectionChange(){const t=document.getSelection();if(!t)return;const e=t.getRangeAt(0);if(!0!==e.collapsed||0!==e.startOffset)return;const n=this.quill.scroll.find(e.startContainer);if(!(n instanceof u.ParentBlot&&n.uiNode))return;const r=document.createRange();r.setStartAfter(n.uiNode),r.setEndAfter(n.uiNode),t.removeAllRanges(),t.addRange(r)}}var C=j;r.Ay.register({"blots/block":i.Ay,"blots/block/embed":i.zo,"blots/break":s.A,"blots/container":o.A,"blots/cursor":l.A,"blots/embed":a.A,"blots/inline":c.A,"blots/scroll":y,"blots/text":v.A,"modules/clipboard":A.Ay,"modules/history":N,"modules/keyboard":q.Ay,"modules/uploader":_,"modules/input":O,"modules/uiNode":C});var R=r.Ay},5374:function(t,e,n){"use strict";n.d(e,{A:function(){return o}});var r=n(8920),i=n(7356);const s=(0,n(6078).A)("quill:events");["selectionchange","mousedown","mouseup","click"].forEach((t=>{document.addEventListener(t,(function(){for(var t=arguments.length,e=new Array(t),n=0;n{const n=i.A.get(t);n&&n.emitter&&n.emitter.handleDOM(...e)}))}))}));var o=class extends r{static events={EDITOR_CHANGE:"editor-change",SCROLL_BEFORE_UPDATE:"scroll-before-update",SCROLL_BLOT_MOUNT:"scroll-blot-mount",SCROLL_BLOT_UNMOUNT:"scroll-blot-unmount",SCROLL_OPTIMIZE:"scroll-optimize",SCROLL_UPDATE:"scroll-update",SCROLL_EMBED_UPDATE:"scroll-embed-update",SELECTION_CHANGE:"selection-change",TEXT_CHANGE:"text-change",COMPOSITION_BEFORE_START:"composition-before-start",COMPOSITION_START:"composition-start",COMPOSITION_BEFORE_END:"composition-before-end",COMPOSITION_END:"composition-end"};static sources={API:"api",SILENT:"silent",USER:"user"};constructor(){super(),this.domListeners={},this.on("error",s.error)}emit(){for(var t=arguments.length,e=new Array(t),n=0;n1?e-1:0),r=1;r{let{node:r,handler:i}=e;(t.target===r||r.contains(t.target))&&i(t,...n)}))}listenDOM(t,e,n){this.domListeners[t]||(this.domListeners[t]=[]),this.domListeners[t].push({node:e,handler:n})}}},7356:function(t,e){"use strict";e.A=new WeakMap},6078:function(t,e){"use strict";const n=["error","warn","log","info"];let r="warn";function i(t){if(r&&n.indexOf(t)<=n.indexOf(r)){for(var e=arguments.length,i=new Array(e>1?e-1:0),s=1;s(e[n]=i.bind(console,n,t),e)),{})}s.level=t=>{r=t},i.level=s.level,e.A=s},4266:function(t,e){"use strict";e.A=class{static DEFAULTS={};constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.quill=t,this.options=e}}},6142:function(t,e,n){"use strict";n.d(e,{Ay:function(){return I}});var r=n(8347),i=n(6003),s=n(5232),o=n.n(s),l=n(3707),a=n(5123),c=n(9698),u=n(3036),h=n(4541),d=n(5508),f=n(8298);const p=/^[ -~]*$/;function g(t,e,n){if(0===t.length){const[t]=y(n.pop());return e<=0?``:`${g([],e-1,n)}`}const[{child:r,offset:i,length:s,indent:o,type:l},...a]=t,[c,u]=y(l);if(o>e)return n.push(l),o===e+1?`<${c}>${m(r,i,s)}${g(a,o,n)}`:`<${c}>
  • ${g(t,e+1,n)}`;const h=n[n.length-1];if(o===e&&l===h)return`
  • ${m(r,i,s)}${g(a,o,n)}`;const[d]=y(n.pop());return`${g(t,e-1,n)}`}function m(t,e,n){let r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if("html"in t&&"function"==typeof t.html)return t.html(e,n);if(t instanceof d.A)return(0,d.X)(t.value().slice(e,e+n));if(t instanceof i.ParentBlot){if("list-container"===t.statics.blotName){const r=[];return t.children.forEachAt(e,n,((t,e,n)=>{const i="formats"in t&&"function"==typeof t.formats?t.formats():{};r.push({child:t,offset:e,length:n,indent:i.indent||0,type:i.list})})),g(r,-1,[])}const i=[];if(t.children.forEachAt(e,n,((t,e,n)=>{i.push(m(t,e,n))})),r||"list"===t.statics.blotName)return i.join("");const{outerHTML:s,innerHTML:o}=t.domNode,[l,a]=s.split(`>${o}<`);return"${i.join("")}<${a}`:`${l}>${i.join("")}<${a}`}return t.domNode instanceof Element?t.domNode.outerHTML:""}function b(t,e){return Object.keys(e).reduce(((n,r)=>{if(null==t[r])return n;const i=e[r];return i===t[r]?n[r]=i:Array.isArray(i)?i.indexOf(t[r])<0?n[r]=i.concat([t[r]]):n[r]=i:n[r]=[i,t[r]],n}),{})}function y(t){const e="ordered"===t?"ol":"ul";switch(t){case"checked":return[e,' data-list="checked"'];case"unchecked":return[e,' data-list="unchecked"'];default:return[e,""]}}function v(t){return t.reduce(((t,e)=>{if("string"==typeof e.insert){const n=e.insert.replace(/\r\n/g,"\n").replace(/\r/g,"\n");return t.insert(n,e.attributes)}return t.push(e)}),new(o()))}function A(t,e){let{index:n,length:r}=t;return new f.Q(n+e,r)}var x=class{constructor(t){this.scroll=t,this.delta=this.getDelta()}applyDelta(t){this.scroll.update();let e=this.scroll.length();this.scroll.batchStart();const n=v(t),l=new(o());return function(t){const e=[];return t.forEach((t=>{"string"==typeof t.insert?t.insert.split("\n").forEach(((n,r)=>{r&&e.push({insert:"\n",attributes:t.attributes}),n&&e.push({insert:n,attributes:t.attributes})})):e.push(t)})),e}(n.ops.slice()).reduce(((t,n)=>{const o=s.Op.length(n);let a=n.attributes||{},u=!1,h=!1;if(null!=n.insert){if(l.retain(o),"string"==typeof n.insert){const o=n.insert;h=!o.endsWith("\n")&&(e<=t||!!this.scroll.descendant(c.zo,t)[0]),this.scroll.insertAt(t,o);const[l,u]=this.scroll.line(t);let d=(0,r.A)({},(0,c.Ji)(l));if(l instanceof c.Ay){const[t]=l.descendant(i.LeafBlot,u);t&&(d=(0,r.A)(d,(0,c.Ji)(t)))}a=s.AttributeMap.diff(d,a)||{}}else if("object"==typeof n.insert){const o=Object.keys(n.insert)[0];if(null==o)return t;const l=null!=this.scroll.query(o,i.Scope.INLINE);if(l)(e<=t||this.scroll.descendant(c.zo,t)[0])&&(h=!0);else if(t>0){const[e,n]=this.scroll.descendant(i.LeafBlot,t-1);e instanceof d.A?"\n"!==e.value()[n]&&(u=!0):e instanceof i.EmbedBlot&&e.statics.scope===i.Scope.INLINE_BLOT&&(u=!0)}if(this.scroll.insertAt(t,o,n.insert[o]),l){const[e]=this.scroll.descendant(i.LeafBlot,t);if(e){const t=(0,r.A)({},(0,c.Ji)(e));a=s.AttributeMap.diff(t,a)||{}}}}e+=o}else if(l.push(n),null!==n.retain&&"object"==typeof n.retain){const e=Object.keys(n.retain)[0];if(null==e)return t;this.scroll.updateEmbedAt(t,e,n.retain[e])}Object.keys(a).forEach((e=>{this.scroll.formatAt(t,o,e,a[e])}));const f=u?1:0,p=h?1:0;return e+=f+p,l.retain(f),l.delete(p),t+o+f+p}),0),l.reduce(((t,e)=>"number"==typeof e.delete?(this.scroll.deleteAt(t,e.delete),t):t+s.Op.length(e)),0),this.scroll.batchEnd(),this.scroll.optimize(),this.update(n)}deleteText(t,e){return this.scroll.deleteAt(t,e),this.update((new(o())).retain(t).delete(e))}formatLine(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.scroll.update(),Object.keys(n).forEach((r=>{this.scroll.lines(t,Math.max(e,1)).forEach((t=>{t.format(r,n[r])}))})),this.scroll.optimize();const r=(new(o())).retain(t).retain(e,(0,l.A)(n));return this.update(r)}formatText(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};Object.keys(n).forEach((r=>{this.scroll.formatAt(t,e,r,n[r])}));const r=(new(o())).retain(t).retain(e,(0,l.A)(n));return this.update(r)}getContents(t,e){return this.delta.slice(t,t+e)}getDelta(){return this.scroll.lines().reduce(((t,e)=>t.concat(e.delta())),new(o()))}getFormat(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=[],r=[];0===e?this.scroll.path(t).forEach((t=>{const[e]=t;e instanceof c.Ay?n.push(e):e instanceof i.LeafBlot&&r.push(e)})):(n=this.scroll.lines(t,e),r=this.scroll.descendants(i.LeafBlot,t,e));const[s,o]=[n,r].map((t=>{const e=t.shift();if(null==e)return{};let n=(0,c.Ji)(e);for(;Object.keys(n).length>0;){const e=t.shift();if(null==e)return n;n=b((0,c.Ji)(e),n)}return n}));return{...s,...o}}getHTML(t,e){const[n,r]=this.scroll.line(t);if(n){const i=n.length();return n.length()>=r+e&&(0!==r||e!==i)?m(n,r,e,!0):m(this.scroll,t,e,!0)}return""}getText(t,e){return this.getContents(t,e).filter((t=>"string"==typeof t.insert)).map((t=>t.insert)).join("")}insertContents(t,e){const n=v(e),r=(new(o())).retain(t).concat(n);return this.scroll.insertContents(t,n),this.update(r)}insertEmbed(t,e,n){return this.scroll.insertAt(t,e,n),this.update((new(o())).retain(t).insert({[e]:n}))}insertText(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return e=e.replace(/\r\n/g,"\n").replace(/\r/g,"\n"),this.scroll.insertAt(t,e),Object.keys(n).forEach((r=>{this.scroll.formatAt(t,e.length,r,n[r])})),this.update((new(o())).retain(t).insert(e,(0,l.A)(n)))}isBlank(){if(0===this.scroll.children.length)return!0;if(this.scroll.children.length>1)return!1;const t=this.scroll.children.head;if(t?.statics.blotName!==c.Ay.blotName)return!1;const e=t;return!(e.children.length>1)&&e.children.head instanceof u.A}removeFormat(t,e){const n=this.getText(t,e),[r,i]=this.scroll.line(t+e);let s=0,l=new(o());null!=r&&(s=r.length()-i,l=r.delta().slice(i,i+s-1).insert("\n"));const a=this.getContents(t,e+s).diff((new(o())).insert(n).concat(l)),c=(new(o())).retain(t).concat(a);return this.applyDelta(c)}update(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;const r=this.delta;if(1===e.length&&"characterData"===e[0].type&&e[0].target.data.match(p)&&this.scroll.find(e[0].target)){const i=this.scroll.find(e[0].target),s=(0,c.Ji)(i),l=i.offset(this.scroll),a=e[0].oldValue.replace(h.A.CONTENTS,""),u=(new(o())).insert(a),d=(new(o())).insert(i.value()),f=n&&{oldRange:A(n.oldRange,-l),newRange:A(n.newRange,-l)};t=(new(o())).retain(l).concat(u.diff(d,f)).reduce(((t,e)=>e.insert?t.insert(e.insert,s):t.push(e)),new(o())),this.delta=r.compose(t)}else this.delta=this.getDelta(),t&&(0,a.A)(r.compose(t),this.delta)||(t=r.diff(this.delta,n));return t}},N=n(5374),E=n(7356),w=n(6078),q=n(4266),k=n(746),_=class{isComposing=!1;constructor(t,e){this.scroll=t,this.emitter=e,this.setupListeners()}setupListeners(){this.scroll.domNode.addEventListener("compositionstart",(t=>{this.isComposing||this.handleCompositionStart(t)})),this.scroll.domNode.addEventListener("compositionend",(t=>{this.isComposing&&queueMicrotask((()=>{this.handleCompositionEnd(t)}))}))}handleCompositionStart(t){const e=t.target instanceof Node?this.scroll.find(t.target,!0):null;!e||e instanceof k.A||(this.emitter.emit(N.A.events.COMPOSITION_BEFORE_START,t),this.scroll.batchStart(),this.emitter.emit(N.A.events.COMPOSITION_START,t),this.isComposing=!0)}handleCompositionEnd(t){this.emitter.emit(N.A.events.COMPOSITION_BEFORE_END,t),this.scroll.batchEnd(),this.emitter.emit(N.A.events.COMPOSITION_END,t),this.isComposing=!1}},L=n(9609);const S=t=>{const e=t.getBoundingClientRect(),n="offsetWidth"in t&&Math.abs(e.width)/t.offsetWidth||1,r="offsetHeight"in t&&Math.abs(e.height)/t.offsetHeight||1;return{top:e.top,right:e.left+t.clientWidth*n,bottom:e.top+t.clientHeight*r,left:e.left}},O=t=>{const e=parseInt(t,10);return Number.isNaN(e)?0:e},T=(t,e,n,r,i,s)=>tr?0:tr?e-t>r-n?t+i-n:e-r+s:0;const j=["block","break","cursor","inline","scroll","text"];const C=(0,w.A)("quill"),R=new i.Registry;i.ParentBlot.uiClass="ql-ui";class I{static DEFAULTS={bounds:null,modules:{clipboard:!0,keyboard:!0,history:!0,uploader:!0},placeholder:"",readOnly:!1,registry:R,theme:"default"};static events=N.A.events;static sources=N.A.sources;static version="2.0.2";static imports={delta:o(),parchment:i,"core/module":q.A,"core/theme":L.A};static debug(t){!0===t&&(t="log"),w.A.level(t)}static find(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return E.A.get(t)||R.find(t,e)}static import(t){return null==this.imports[t]&&C.error(`Cannot import ${t}. Are you sure it was registered?`),this.imports[t]}static register(){if("string"!=typeof(arguments.length<=0?void 0:arguments[0])){const t=arguments.length<=0?void 0:arguments[0],e=!!(arguments.length<=1?void 0:arguments[1]),n="attrName"in t?t.attrName:t.blotName;"string"==typeof n?this.register(`formats/${n}`,t,e):Object.keys(t).forEach((n=>{this.register(n,t[n],e)}))}else{const t=arguments.length<=0?void 0:arguments[0],e=arguments.length<=1?void 0:arguments[1],n=!!(arguments.length<=2?void 0:arguments[2]);null==this.imports[t]||n||C.warn(`Overwriting ${t} with`,e),this.imports[t]=e,(t.startsWith("blots/")||t.startsWith("formats/"))&&e&&"boolean"!=typeof e&&"abstract"!==e.blotName&&R.register(e),"function"==typeof e.register&&e.register(R)}}constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.options=function(t,e){const n=B(t);if(!n)throw new Error("Invalid Quill container");const s=!e.theme||e.theme===I.DEFAULTS.theme?L.A:I.import(`themes/${e.theme}`);if(!s)throw new Error(`Invalid theme ${e.theme}. Did you register it?`);const{modules:o,...l}=I.DEFAULTS,{modules:a,...c}=s.DEFAULTS;let u=M(e.modules);null!=u&&u.toolbar&&u.toolbar.constructor!==Object&&(u={...u,toolbar:{container:u.toolbar}});const h=(0,r.A)({},M(o),M(a),u),d={...l,...U(c),...U(e)};let f=e.registry;return f?e.formats&&C.warn('Ignoring "formats" option because "registry" is specified'):f=e.formats?((t,e,n)=>{const r=new i.Registry;return j.forEach((t=>{const n=e.query(t);n&&r.register(n)})),t.forEach((t=>{let i=e.query(t);i||n.error(`Cannot register "${t}" specified in "formats" config. Are you sure it was registered?`);let s=0;for(;i;)if(r.register(i),i="blotName"in i?i.requiredContainer??null:null,s+=1,s>100){n.error(`Cycle detected in registering blot requiredContainer: "${t}"`);break}})),r})(e.formats,d.registry,C):d.registry,{...d,registry:f,container:n,theme:s,modules:Object.entries(h).reduce(((t,e)=>{let[n,i]=e;if(!i)return t;const s=I.import(`modules/${n}`);return null==s?(C.error(`Cannot load ${n} module. Are you sure you registered it?`),t):{...t,[n]:(0,r.A)({},s.DEFAULTS||{},i)}}),{}),bounds:B(d.bounds)}}(t,e),this.container=this.options.container,null==this.container)return void C.error("Invalid Quill container",t);this.options.debug&&I.debug(this.options.debug);const n=this.container.innerHTML.trim();this.container.classList.add("ql-container"),this.container.innerHTML="",E.A.set(this.container,this),this.root=this.addContainer("ql-editor"),this.root.classList.add("ql-blank"),this.emitter=new N.A;const s=i.ScrollBlot.blotName,l=this.options.registry.query(s);if(!l||!("blotName"in l))throw new Error(`Cannot initialize Quill without "${s}" blot`);if(this.scroll=new l(this.options.registry,this.root,{emitter:this.emitter}),this.editor=new x(this.scroll),this.selection=new f.A(this.scroll,this.emitter),this.composition=new _(this.scroll,this.emitter),this.theme=new this.options.theme(this,this.options),this.keyboard=this.theme.addModule("keyboard"),this.clipboard=this.theme.addModule("clipboard"),this.history=this.theme.addModule("history"),this.uploader=this.theme.addModule("uploader"),this.theme.addModule("input"),this.theme.addModule("uiNode"),this.theme.init(),this.emitter.on(N.A.events.EDITOR_CHANGE,(t=>{t===N.A.events.TEXT_CHANGE&&this.root.classList.toggle("ql-blank",this.editor.isBlank())})),this.emitter.on(N.A.events.SCROLL_UPDATE,((t,e)=>{const n=this.selection.lastRange,[r]=this.selection.getRange(),i=n&&r?{oldRange:n,newRange:r}:void 0;D.call(this,(()=>this.editor.update(null,e,i)),t)})),this.emitter.on(N.A.events.SCROLL_EMBED_UPDATE,((t,e)=>{const n=this.selection.lastRange,[r]=this.selection.getRange(),i=n&&r?{oldRange:n,newRange:r}:void 0;D.call(this,(()=>{const n=(new(o())).retain(t.offset(this)).retain({[t.statics.blotName]:e});return this.editor.update(n,[],i)}),I.sources.USER)})),n){const t=this.clipboard.convert({html:`${n}


    `,text:"\n"});this.setContents(t)}this.history.clear(),this.options.placeholder&&this.root.setAttribute("data-placeholder",this.options.placeholder),this.options.readOnly&&this.disable(),this.allowReadOnlyEdits=!1}addContainer(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if("string"==typeof t){const e=t;(t=document.createElement("div")).classList.add(e)}return this.container.insertBefore(t,e),t}blur(){this.selection.setRange(null)}deleteText(t,e,n){return[t,e,,n]=P(t,e,n),D.call(this,(()=>this.editor.deleteText(t,e)),n,t,-1*e)}disable(){this.enable(!1)}editReadOnly(t){this.allowReadOnlyEdits=!0;const e=t();return this.allowReadOnlyEdits=!1,e}enable(){let t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.scroll.enable(t),this.container.classList.toggle("ql-disabled",!t)}focus(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.selection.focus(),t.preventScroll||this.scrollSelectionIntoView()}format(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:N.A.sources.API;return D.call(this,(()=>{const n=this.getSelection(!0);let r=new(o());if(null==n)return r;if(this.scroll.query(t,i.Scope.BLOCK))r=this.editor.formatLine(n.index,n.length,{[t]:e});else{if(0===n.length)return this.selection.format(t,e),r;r=this.editor.formatText(n.index,n.length,{[t]:e})}return this.setSelection(n,N.A.sources.SILENT),r}),n)}formatLine(t,e,n,r,i){let s;return[t,e,s,i]=P(t,e,n,r,i),D.call(this,(()=>this.editor.formatLine(t,e,s)),i,t,0)}formatText(t,e,n,r,i){let s;return[t,e,s,i]=P(t,e,n,r,i),D.call(this,(()=>this.editor.formatText(t,e,s)),i,t,0)}getBounds(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=null;if(n="number"==typeof t?this.selection.getBounds(t,e):this.selection.getBounds(t.index,t.length),!n)return null;const r=this.container.getBoundingClientRect();return{bottom:n.bottom-r.top,height:n.height,left:n.left-r.left,right:n.right-r.left,top:n.top-r.top,width:n.width}}getContents(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.getLength()-t;return[t,e]=P(t,e),this.editor.getContents(t,e)}getFormat(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.getSelection(!0),e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return"number"==typeof t?this.editor.getFormat(t,e):this.editor.getFormat(t.index,t.length)}getIndex(t){return t.offset(this.scroll)}getLength(){return this.scroll.length()}getLeaf(t){return this.scroll.leaf(t)}getLine(t){return this.scroll.line(t)}getLines(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Number.MAX_VALUE;return"number"!=typeof t?this.scroll.lines(t.index,t.length):this.scroll.lines(t,e)}getModule(t){return this.theme.modules[t]}getSelection(){return arguments.length>0&&void 0!==arguments[0]&&arguments[0]&&this.focus(),this.update(),this.selection.getRange()[0]}getSemanticHTML(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1?arguments[1]:void 0;return"number"==typeof t&&(e=e??this.getLength()-t),[t,e]=P(t,e),this.editor.getHTML(t,e)}getText(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1?arguments[1]:void 0;return"number"==typeof t&&(e=e??this.getLength()-t),[t,e]=P(t,e),this.editor.getText(t,e)}hasFocus(){return this.selection.hasFocus()}insertEmbed(t,e,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:I.sources.API;return D.call(this,(()=>this.editor.insertEmbed(t,e,n)),r,t)}insertText(t,e,n,r,i){let s;return[t,,s,i]=P(t,0,n,r,i),D.call(this,(()=>this.editor.insertText(t,e,s)),i,t,e.length)}isEnabled(){return this.scroll.isEnabled()}off(){return this.emitter.off(...arguments)}on(){return this.emitter.on(...arguments)}once(){return this.emitter.once(...arguments)}removeFormat(t,e,n){return[t,e,,n]=P(t,e,n),D.call(this,(()=>this.editor.removeFormat(t,e)),n,t)}scrollRectIntoView(t){((t,e)=>{const n=t.ownerDocument;let r=e,i=t;for(;i;){const t=i===n.body,e=t?{top:0,right:window.visualViewport?.width??n.documentElement.clientWidth,bottom:window.visualViewport?.height??n.documentElement.clientHeight,left:0}:S(i),o=getComputedStyle(i),l=T(r.left,r.right,e.left,e.right,O(o.scrollPaddingLeft),O(o.scrollPaddingRight)),a=T(r.top,r.bottom,e.top,e.bottom,O(o.scrollPaddingTop),O(o.scrollPaddingBottom));if(l||a)if(t)n.defaultView?.scrollBy(l,a);else{const{scrollLeft:t,scrollTop:e}=i;a&&(i.scrollTop+=a),l&&(i.scrollLeft+=l);const n=i.scrollLeft-t,s=i.scrollTop-e;r={left:r.left-n,top:r.top-s,right:r.right-n,bottom:r.bottom-s}}i=t||"fixed"===o.position?null:(s=i).parentElement||s.getRootNode().host||null}var s})(this.root,t)}scrollIntoView(){console.warn("Quill#scrollIntoView() has been deprecated and will be removed in the near future. Please use Quill#scrollSelectionIntoView() instead."),this.scrollSelectionIntoView()}scrollSelectionIntoView(){const t=this.selection.lastRange,e=t&&this.selection.getBounds(t.index,t.length);e&&this.scrollRectIntoView(e)}setContents(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:N.A.sources.API;return D.call(this,(()=>{t=new(o())(t);const e=this.getLength(),n=this.editor.deleteText(0,e),r=this.editor.insertContents(0,t),i=this.editor.deleteText(this.getLength()-1,1);return n.compose(r).compose(i)}),e)}setSelection(t,e,n){null==t?this.selection.setRange(null,e||I.sources.API):([t,e,,n]=P(t,e,n),this.selection.setRange(new f.Q(Math.max(0,t),e),n),n!==N.A.sources.SILENT&&this.scrollSelectionIntoView())}setText(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:N.A.sources.API;const n=(new(o())).insert(t);return this.setContents(n,e)}update(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:N.A.sources.USER;const e=this.scroll.update(t);return this.selection.update(t),e}updateContents(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:N.A.sources.API;return D.call(this,(()=>(t=new(o())(t),this.editor.applyDelta(t))),e,!0)}}function B(t){return"string"==typeof t?document.querySelector(t):t}function M(t){return Object.entries(t??{}).reduce(((t,e)=>{let[n,r]=e;return{...t,[n]:!0===r?{}:r}}),{})}function U(t){return Object.fromEntries(Object.entries(t).filter((t=>void 0!==t[1])))}function D(t,e,n,r){if(!this.isEnabled()&&e===N.A.sources.USER&&!this.allowReadOnlyEdits)return new(o());let i=null==n?null:this.getSelection();const s=this.editor.delta,l=t();if(null!=i&&(!0===n&&(n=i.index),null==r?i=z(i,l,e):0!==r&&(i=z(i,n,r,e)),this.setSelection(i,N.A.sources.SILENT)),l.length()>0){const t=[N.A.events.TEXT_CHANGE,l,s,e];this.emitter.emit(N.A.events.EDITOR_CHANGE,...t),e!==N.A.sources.SILENT&&this.emitter.emit(...t)}return l}function P(t,e,n,r,i){let s={};return"number"==typeof t.index&&"number"==typeof t.length?"number"!=typeof e?(i=r,r=n,n=e,e=t.length,t=t.index):(e=t.length,t=t.index):"number"!=typeof e&&(i=r,r=n,n=e,e=0),"object"==typeof n?(s=n,i=r):"string"==typeof n&&(null!=r?s[n]=r:i=n),[t,e,s,i=i||N.A.sources.API]}function z(t,e,n,r){const i="number"==typeof n?n:0;if(null==t)return null;let s,o;return e&&"function"==typeof e.transformPosition?[s,o]=[t.index,t.index+t.length].map((t=>e.transformPosition(t,r!==N.A.sources.USER))):[s,o]=[t.index,t.index+t.length].map((t=>t=0?t+i:Math.max(e,t+i))),new f.Q(s,o-s)}},8298:function(t,e,n){"use strict";n.d(e,{Q:function(){return a}});var r=n(6003),i=n(5123),s=n(3707),o=n(5374);const l=(0,n(6078).A)("quill:selection");class a{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;this.index=t,this.length=e}}function c(t,e){try{e.parentNode}catch(t){return!1}return t.contains(e)}e.A=class{constructor(t,e){this.emitter=e,this.scroll=t,this.composing=!1,this.mouseDown=!1,this.root=this.scroll.domNode,this.cursor=this.scroll.create("cursor",this),this.savedRange=new a(0,0),this.lastRange=this.savedRange,this.lastNative=null,this.handleComposition(),this.handleDragging(),this.emitter.listenDOM("selectionchange",document,(()=>{this.mouseDown||this.composing||setTimeout(this.update.bind(this,o.A.sources.USER),1)})),this.emitter.on(o.A.events.SCROLL_BEFORE_UPDATE,(()=>{if(!this.hasFocus())return;const t=this.getNativeRange();null!=t&&t.start.node!==this.cursor.textNode&&this.emitter.once(o.A.events.SCROLL_UPDATE,((e,n)=>{try{this.root.contains(t.start.node)&&this.root.contains(t.end.node)&&this.setNativeRange(t.start.node,t.start.offset,t.end.node,t.end.offset);const r=n.some((t=>"characterData"===t.type||"childList"===t.type||"attributes"===t.type&&t.target===this.root));this.update(r?o.A.sources.SILENT:e)}catch(t){}}))})),this.emitter.on(o.A.events.SCROLL_OPTIMIZE,((t,e)=>{if(e.range){const{startNode:t,startOffset:n,endNode:r,endOffset:i}=e.range;this.setNativeRange(t,n,r,i),this.update(o.A.sources.SILENT)}})),this.update(o.A.sources.SILENT)}handleComposition(){this.emitter.on(o.A.events.COMPOSITION_BEFORE_START,(()=>{this.composing=!0})),this.emitter.on(o.A.events.COMPOSITION_END,(()=>{if(this.composing=!1,this.cursor.parent){const t=this.cursor.restore();if(!t)return;setTimeout((()=>{this.setNativeRange(t.startNode,t.startOffset,t.endNode,t.endOffset)}),1)}}))}handleDragging(){this.emitter.listenDOM("mousedown",document.body,(()=>{this.mouseDown=!0})),this.emitter.listenDOM("mouseup",document.body,(()=>{this.mouseDown=!1,this.update(o.A.sources.USER)}))}focus(){this.hasFocus()||(this.root.focus({preventScroll:!0}),this.setRange(this.savedRange))}format(t,e){this.scroll.update();const n=this.getNativeRange();if(null!=n&&n.native.collapsed&&!this.scroll.query(t,r.Scope.BLOCK)){if(n.start.node!==this.cursor.textNode){const t=this.scroll.find(n.start.node,!1);if(null==t)return;if(t instanceof r.LeafBlot){const e=t.split(n.start.offset);t.parent.insertBefore(this.cursor,e)}else t.insertBefore(this.cursor,n.start.node);this.cursor.attach()}this.cursor.format(t,e),this.scroll.optimize(),this.setNativeRange(this.cursor.textNode,this.cursor.textNode.data.length),this.update()}}getBounds(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;const n=this.scroll.length();let r;t=Math.min(t,n-1),e=Math.min(t+e,n-1)-t;let[i,s]=this.scroll.leaf(t);if(null==i)return null;if(e>0&&s===i.length()){const[e]=this.scroll.leaf(t+1);if(e){const[n]=this.scroll.line(t),[r]=this.scroll.line(t+1);n===r&&(i=e,s=0)}}[r,s]=i.position(s,!0);const o=document.createRange();if(e>0)return o.setStart(r,s),[i,s]=this.scroll.leaf(t+e),null==i?null:([r,s]=i.position(s,!0),o.setEnd(r,s),o.getBoundingClientRect());let l,a="left";if(r instanceof Text){if(!r.data.length)return null;s0&&(a="right")}return{bottom:l.top+l.height,height:l.height,left:l[a],right:l[a],top:l.top,width:0}}getNativeRange(){const t=document.getSelection();if(null==t||t.rangeCount<=0)return null;const e=t.getRangeAt(0);if(null==e)return null;const n=this.normalizeNative(e);return l.info("getNativeRange",n),n}getRange(){const t=this.scroll.domNode;if("isConnected"in t&&!t.isConnected)return[null,null];const e=this.getNativeRange();return null==e?[null,null]:[this.normalizedToRange(e),e]}hasFocus(){return document.activeElement===this.root||null!=document.activeElement&&c(this.root,document.activeElement)}normalizedToRange(t){const e=[[t.start.node,t.start.offset]];t.native.collapsed||e.push([t.end.node,t.end.offset]);const n=e.map((t=>{const[e,n]=t,i=this.scroll.find(e,!0),s=i.offset(this.scroll);return 0===n?s:i instanceof r.LeafBlot?s+i.index(e,n):s+i.length()})),i=Math.min(Math.max(...n),this.scroll.length()-1),s=Math.min(i,...n);return new a(s,i-s)}normalizeNative(t){if(!c(this.root,t.startContainer)||!t.collapsed&&!c(this.root,t.endContainer))return null;const e={start:{node:t.startContainer,offset:t.startOffset},end:{node:t.endContainer,offset:t.endOffset},native:t};return[e.start,e.end].forEach((t=>{let{node:e,offset:n}=t;for(;!(e instanceof Text)&&e.childNodes.length>0;)if(e.childNodes.length>n)e=e.childNodes[n],n=0;else{if(e.childNodes.length!==n)break;e=e.lastChild,n=e instanceof Text?e.data.length:e.childNodes.length>0?e.childNodes.length:e.childNodes.length+1}t.node=e,t.offset=n})),e}rangeToNative(t){const e=this.scroll.length(),n=(t,n)=>{t=Math.min(e-1,t);const[r,i]=this.scroll.leaf(t);return r?r.position(i,n):[null,-1]};return[...n(t.index,!1),...n(t.index+t.length,!0)]}setNativeRange(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:e,i=arguments.length>4&&void 0!==arguments[4]&&arguments[4];if(l.info("setNativeRange",t,e,n,r),null!=t&&(null==this.root.parentNode||null==t.parentNode||null==n.parentNode))return;const s=document.getSelection();if(null!=s)if(null!=t){this.hasFocus()||this.root.focus({preventScroll:!0});const{native:o}=this.getNativeRange()||{};if(null==o||i||t!==o.startContainer||e!==o.startOffset||n!==o.endContainer||r!==o.endOffset){t instanceof Element&&"BR"===t.tagName&&(e=Array.from(t.parentNode.childNodes).indexOf(t),t=t.parentNode),n instanceof Element&&"BR"===n.tagName&&(r=Array.from(n.parentNode.childNodes).indexOf(n),n=n.parentNode);const i=document.createRange();i.setStart(t,e),i.setEnd(n,r),s.removeAllRanges(),s.addRange(i)}}else s.removeAllRanges(),this.root.blur()}setRange(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:o.A.sources.API;if("string"==typeof e&&(n=e,e=!1),l.info("setRange",t),null!=t){const n=this.rangeToNative(t);this.setNativeRange(...n,e)}else this.setNativeRange(null);this.update(n)}update(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:o.A.sources.USER;const e=this.lastRange,[n,r]=this.getRange();if(this.lastRange=n,this.lastNative=r,null!=this.lastRange&&(this.savedRange=this.lastRange),!(0,i.A)(e,this.lastRange)){if(!this.composing&&null!=r&&r.native.collapsed&&r.start.node!==this.cursor.textNode){const t=this.cursor.restore();t&&this.setNativeRange(t.startNode,t.startOffset,t.endNode,t.endOffset)}const n=[o.A.events.SELECTION_CHANGE,(0,s.A)(this.lastRange),(0,s.A)(e),t];this.emitter.emit(o.A.events.EDITOR_CHANGE,...n),t!==o.A.sources.SILENT&&this.emitter.emit(...n)}}}},9609:function(t,e){"use strict";class n{static DEFAULTS={modules:{}};static themes={default:n};modules={};constructor(t,e){this.quill=t,this.options=e}init(){Object.keys(this.options.modules).forEach((t=>{null==this.modules[t]&&this.addModule(t)}))}addModule(t){const e=this.quill.constructor.import(`modules/${t}`);return this.modules[t]=new e(this.quill,this.options.modules[t]||{}),this.modules[t]}}e.A=n},8276:function(t,e,n){"use strict";n.d(e,{Hu:function(){return l},gS:function(){return s},qh:function(){return o}});var r=n(6003);const i={scope:r.Scope.BLOCK,whitelist:["right","center","justify"]},s=new r.Attributor("align","align",i),o=new r.ClassAttributor("align","ql-align",i),l=new r.StyleAttributor("align","text-align",i)},9541:function(t,e,n){"use strict";n.d(e,{l:function(){return s},s:function(){return o}});var r=n(6003),i=n(8638);const s=new r.ClassAttributor("background","ql-bg",{scope:r.Scope.INLINE}),o=new i.a2("background","background-color",{scope:r.Scope.INLINE})},9404:function(t,e,n){"use strict";n.d(e,{Ay:function(){return h},Cy:function(){return d},EJ:function(){return u}});var r=n(9698),i=n(3036),s=n(4541),o=n(4850),l=n(5508),a=n(580),c=n(6142);class u extends a.A{static create(t){const e=super.create(t);return e.setAttribute("spellcheck","false"),e}code(t,e){return this.children.map((t=>t.length()<=1?"":t.domNode.innerText)).join("\n").slice(t,t+e)}html(t,e){return`
    \n${(0,l.X)(this.code(t,e))}\n
    `}}class h extends r.Ay{static TAB=" ";static register(){c.Ay.register(u)}}class d extends o.A{}d.blotName="code",d.tagName="CODE",h.blotName="code-block",h.className="ql-code-block",h.tagName="DIV",u.blotName="code-block-container",u.className="ql-code-block-container",u.tagName="DIV",u.allowedChildren=[h],h.allowedChildren=[l.A,i.A,s.A],h.requiredContainer=u},8638:function(t,e,n){"use strict";n.d(e,{JM:function(){return o},a2:function(){return i},g3:function(){return s}});var r=n(6003);class i extends r.StyleAttributor{value(t){let e=super.value(t);return e.startsWith("rgb(")?(e=e.replace(/^[^\d]+/,"").replace(/[^\d]+$/,""),`#${e.split(",").map((t=>`00${parseInt(t,10).toString(16)}`.slice(-2))).join("")}`):e}}const s=new r.ClassAttributor("color","ql-color",{scope:r.Scope.INLINE}),o=new i("color","color",{scope:r.Scope.INLINE})},7912:function(t,e,n){"use strict";n.d(e,{Mc:function(){return s},VL:function(){return l},sY:function(){return o}});var r=n(6003);const i={scope:r.Scope.BLOCK,whitelist:["rtl"]},s=new r.Attributor("direction","dir",i),o=new r.ClassAttributor("direction","ql-direction",i),l=new r.StyleAttributor("direction","direction",i)},6772:function(t,e,n){"use strict";n.d(e,{q:function(){return s},z:function(){return l}});var r=n(6003);const i={scope:r.Scope.INLINE,whitelist:["serif","monospace"]},s=new r.ClassAttributor("font","ql-font",i);class o extends r.StyleAttributor{value(t){return super.value(t).replace(/["']/g,"")}}const l=new o("font","font-family",i)},664:function(t,e,n){"use strict";n.d(e,{U:function(){return i},r:function(){return s}});var r=n(6003);const i=new r.ClassAttributor("size","ql-size",{scope:r.Scope.INLINE,whitelist:["small","large","huge"]}),s=new r.StyleAttributor("size","font-size",{scope:r.Scope.INLINE,whitelist:["10px","18px","32px"]})},584:function(t,e,n){"use strict";n.d(e,{Ay:function(){return S},hV:function(){return I}});var r=n(6003),i=n(5232),s=n.n(i),o=n(9698),l=n(6078),a=n(4266),c=n(6142),u=n(8276),h=n(9541),d=n(9404),f=n(8638),p=n(7912),g=n(6772),m=n(664),b=n(8123);const y=/font-weight:\s*normal/,v=["P","OL","UL"],A=t=>t&&v.includes(t.tagName),x=/\bmso-list:[^;]*ignore/i,N=/\bmso-list:[^;]*\bl(\d+)/i,E=/\bmso-list:[^;]*\blevel(\d+)/i,w=[function(t){"urn:schemas-microsoft-com:office:word"===t.documentElement.getAttribute("xmlns:w")&&(t=>{const e=Array.from(t.querySelectorAll("[style*=mso-list]")),n=[],r=[];e.forEach((t=>{(t.getAttribute("style")||"").match(x)?n.push(t):r.push(t)})),n.forEach((t=>t.parentNode?.removeChild(t)));const i=t.documentElement.innerHTML,s=r.map((t=>((t,e)=>{const n=t.getAttribute("style"),r=n?.match(N);if(!r)return null;const i=Number(r[1]),s=n?.match(E),o=s?Number(s[1]):1,l=new RegExp(`@list l${i}:level${o}\\s*\\{[^\\}]*mso-level-number-format:\\s*([\\w-]+)`,"i"),a=e.match(l);return{id:i,indent:o,type:a&&"bullet"===a[1]?"bullet":"ordered",element:t}})(t,i))).filter((t=>t));for(;s.length;){const t=[];let e=s.shift();for(;e;)t.push(e),e=s.length&&s[0]?.element===e.element.nextElementSibling&&s[0].id===e.id?s.shift():null;const n=document.createElement("ul");t.forEach((t=>{const e=document.createElement("li");e.setAttribute("data-list",t.type),t.indent>1&&e.setAttribute("class","ql-indent-"+(t.indent-1)),e.innerHTML=t.element.innerHTML,n.appendChild(e)}));const r=t[0]?.element,{parentNode:i}=r??{};r&&i?.replaceChild(n,r),t.slice(1).forEach((t=>{let{element:e}=t;i?.removeChild(e)}))}})(t)},function(t){t.querySelector('[id^="docs-internal-guid-"]')&&((t=>{Array.from(t.querySelectorAll('b[style*="font-weight"]')).filter((t=>t.getAttribute("style")?.match(y))).forEach((e=>{const n=t.createDocumentFragment();n.append(...e.childNodes),e.parentNode?.replaceChild(n,e)}))})(t),(t=>{Array.from(t.querySelectorAll("br")).filter((t=>A(t.previousElementSibling)&&A(t.nextElementSibling))).forEach((t=>{t.parentNode?.removeChild(t)}))})(t))}];const q=(0,l.A)("quill:clipboard"),k=[[Node.TEXT_NODE,function(t,e,n){let r=t.data;if("O:P"===t.parentElement?.tagName)return e.insert(r.trim());if(!R(t)){if(0===r.trim().length&&r.includes("\n")&&!function(t,e){return t.previousElementSibling&&t.nextElementSibling&&!j(t.previousElementSibling,e)&&!j(t.nextElementSibling,e)}(t,n))return e;const i=(t,e)=>{const n=e.replace(/[^\u00a0]/g,"");return n.length<1&&t?" ":n};r=r.replace(/\r\n/g," ").replace(/\n/g," "),r=r.replace(/\s\s+/g,i.bind(i,!0)),(null==t.previousSibling&&null!=t.parentElement&&j(t.parentElement,n)||t.previousSibling instanceof Element&&j(t.previousSibling,n))&&(r=r.replace(/^\s+/,i.bind(i,!1))),(null==t.nextSibling&&null!=t.parentElement&&j(t.parentElement,n)||t.nextSibling instanceof Element&&j(t.nextSibling,n))&&(r=r.replace(/\s+$/,i.bind(i,!1)))}return e.insert(r)}],[Node.TEXT_NODE,M],["br",function(t,e){return T(e,"\n")||e.insert("\n"),e}],[Node.ELEMENT_NODE,M],[Node.ELEMENT_NODE,function(t,e,n){const i=n.query(t);if(null==i)return e;if(i.prototype instanceof r.EmbedBlot){const e={},r=i.value(t);if(null!=r)return e[i.blotName]=r,(new(s())).insert(e,i.formats(t,n))}else if(i.prototype instanceof r.BlockBlot&&!T(e,"\n")&&e.insert("\n"),"blotName"in i&&"formats"in i&&"function"==typeof i.formats)return O(e,i.blotName,i.formats(t,n),n);return e}],[Node.ELEMENT_NODE,function(t,e,n){const i=r.Attributor.keys(t),s=r.ClassAttributor.keys(t),o=r.StyleAttributor.keys(t),l={};return i.concat(s).concat(o).forEach((e=>{let i=n.query(e,r.Scope.ATTRIBUTE);null!=i&&(l[i.attrName]=i.value(t),l[i.attrName])||(i=_[e],null==i||i.attrName!==e&&i.keyName!==e||(l[i.attrName]=i.value(t)||void 0),i=L[e],null==i||i.attrName!==e&&i.keyName!==e||(i=L[e],l[i.attrName]=i.value(t)||void 0))})),Object.entries(l).reduce(((t,e)=>{let[r,i]=e;return O(t,r,i,n)}),e)}],[Node.ELEMENT_NODE,function(t,e,n){const r={},i=t.style||{};return"italic"===i.fontStyle&&(r.italic=!0),"underline"===i.textDecoration&&(r.underline=!0),"line-through"===i.textDecoration&&(r.strike=!0),(i.fontWeight?.startsWith("bold")||parseInt(i.fontWeight,10)>=700)&&(r.bold=!0),e=Object.entries(r).reduce(((t,e)=>{let[r,i]=e;return O(t,r,i,n)}),e),parseFloat(i.textIndent||0)>0?(new(s())).insert("\t").concat(e):e}],["li",function(t,e,n){const r=n.query(t);if(null==r||"list"!==r.blotName||!T(e,"\n"))return e;let i=-1,o=t.parentNode;for(;null!=o;)["OL","UL"].includes(o.tagName)&&(i+=1),o=o.parentNode;return i<=0?e:e.reduce(((t,e)=>e.insert?e.attributes&&"number"==typeof e.attributes.indent?t.push(e):t.insert(e.insert,{indent:i,...e.attributes||{}}):t),new(s()))}],["ol, ul",function(t,e,n){const r=t;let i="OL"===r.tagName?"ordered":"bullet";const s=r.getAttribute("data-checked");return s&&(i="true"===s?"checked":"unchecked"),O(e,"list",i,n)}],["pre",function(t,e,n){const r=n.query("code-block");return O(e,"code-block",!r||!("formats"in r)||"function"!=typeof r.formats||r.formats(t,n),n)}],["tr",function(t,e,n){const r="TABLE"===t.parentElement?.tagName?t.parentElement:t.parentElement?.parentElement;return null!=r?O(e,"table",Array.from(r.querySelectorAll("tr")).indexOf(t)+1,n):e}],["b",B("bold")],["i",B("italic")],["strike",B("strike")],["style",function(){return new(s())}]],_=[u.gS,p.Mc].reduce(((t,e)=>(t[e.keyName]=e,t)),{}),L=[u.Hu,h.s,f.JM,p.VL,g.z,m.r].reduce(((t,e)=>(t[e.keyName]=e,t)),{});class S extends a.A{static DEFAULTS={matchers:[]};constructor(t,e){super(t,e),this.quill.root.addEventListener("copy",(t=>this.onCaptureCopy(t,!1))),this.quill.root.addEventListener("cut",(t=>this.onCaptureCopy(t,!0))),this.quill.root.addEventListener("paste",this.onCapturePaste.bind(this)),this.matchers=[],k.concat(this.options.matchers??[]).forEach((t=>{let[e,n]=t;this.addMatcher(e,n)}))}addMatcher(t,e){this.matchers.push([t,e])}convert(t){let{html:e,text:n}=t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(r[d.Ay.blotName])return(new(s())).insert(n||"",{[d.Ay.blotName]:r[d.Ay.blotName]});if(!e)return(new(s())).insert(n||"",r);const i=this.convertHTML(e);return T(i,"\n")&&(null==i.ops[i.ops.length-1].attributes||r.table)?i.compose((new(s())).retain(i.length()-1).delete(1)):i}normalizeHTML(t){(t=>{t.documentElement&&w.forEach((e=>{e(t)}))})(t)}convertHTML(t){const e=(new DOMParser).parseFromString(t,"text/html");this.normalizeHTML(e);const n=e.body,r=new WeakMap,[i,s]=this.prepareMatching(n,r);return I(this.quill.scroll,n,i,s,r)}dangerouslyPasteHTML(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:c.Ay.sources.API;if("string"==typeof t){const n=this.convert({html:t,text:""});this.quill.setContents(n,e),this.quill.setSelection(0,c.Ay.sources.SILENT)}else{const r=this.convert({html:e,text:""});this.quill.updateContents((new(s())).retain(t).concat(r),n),this.quill.setSelection(t+r.length(),c.Ay.sources.SILENT)}}onCaptureCopy(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(t.defaultPrevented)return;t.preventDefault();const[n]=this.quill.selection.getRange();if(null==n)return;const{html:r,text:i}=this.onCopy(n,e);t.clipboardData?.setData("text/plain",i),t.clipboardData?.setData("text/html",r),e&&(0,b.Xo)({range:n,quill:this.quill})}normalizeURIList(t){return t.split(/\r?\n/).filter((t=>"#"!==t[0])).join("\n")}onCapturePaste(t){if(t.defaultPrevented||!this.quill.isEnabled())return;t.preventDefault();const e=this.quill.getSelection(!0);if(null==e)return;const n=t.clipboardData?.getData("text/html");let r=t.clipboardData?.getData("text/plain");if(!n&&!r){const e=t.clipboardData?.getData("text/uri-list");e&&(r=this.normalizeURIList(e))}const i=Array.from(t.clipboardData?.files||[]);if(!n&&i.length>0)this.quill.uploader.upload(e,i);else{if(n&&i.length>0){const t=(new DOMParser).parseFromString(n,"text/html");if(1===t.body.childElementCount&&"IMG"===t.body.firstElementChild?.tagName)return void this.quill.uploader.upload(e,i)}this.onPaste(e,{html:n,text:r})}}onCopy(t){const e=this.quill.getText(t);return{html:this.quill.getSemanticHTML(t),text:e}}onPaste(t,e){let{text:n,html:r}=e;const i=this.quill.getFormat(t.index),o=this.convert({text:n,html:r},i);q.log("onPaste",o,{text:n,html:r});const l=(new(s())).retain(t.index).delete(t.length).concat(o);this.quill.updateContents(l,c.Ay.sources.USER),this.quill.setSelection(l.length()-t.length,c.Ay.sources.SILENT),this.quill.scrollSelectionIntoView()}prepareMatching(t,e){const n=[],r=[];return this.matchers.forEach((i=>{const[s,o]=i;switch(s){case Node.TEXT_NODE:r.push(o);break;case Node.ELEMENT_NODE:n.push(o);break;default:Array.from(t.querySelectorAll(s)).forEach((t=>{if(e.has(t)){const n=e.get(t);n?.push(o)}else e.set(t,[o])}))}})),[n,r]}}function O(t,e,n,r){return r.query(e)?t.reduce(((t,r)=>{if(!r.insert)return t;if(r.attributes&&r.attributes[e])return t.push(r);const i=n?{[e]:n}:{};return t.insert(r.insert,{...i,...r.attributes})}),new(s())):t}function T(t,e){let n="";for(let r=t.ops.length-1;r>=0&&n.lengthr(e,n,t)),new(s())):e.nodeType===e.ELEMENT_NODE?Array.from(e.childNodes||[]).reduce(((s,o)=>{let l=I(t,o,n,r,i);return o.nodeType===e.ELEMENT_NODE&&(l=n.reduce(((e,n)=>n(o,e,t)),l),l=(i.get(o)||[]).reduce(((e,n)=>n(o,e,t)),l)),s.concat(l)}),new(s())):new(s())}function B(t){return(e,n,r)=>O(n,t,!0,r)}function M(t,e,n){if(!T(e,"\n")){if(j(t,n)&&(t.childNodes.length>0||t instanceof HTMLParagraphElement))return e.insert("\n");if(e.length()>0&&t.nextSibling){let r=t.nextSibling;for(;null!=r;){if(j(r,n))return e.insert("\n");const t=n.query(r);if(t&&t.prototype instanceof o.zo)return e.insert("\n");r=r.firstChild}}}return e}},8123:function(t,e,n){"use strict";n.d(e,{Ay:function(){return f},Xo:function(){return v}});var r=n(5123),i=n(3707),s=n(5232),o=n.n(s),l=n(6003),a=n(6142),c=n(6078),u=n(4266);const h=(0,c.A)("quill:keyboard"),d=/Mac/i.test(navigator.platform)?"metaKey":"ctrlKey";class f extends u.A{static match(t,e){return!["altKey","ctrlKey","metaKey","shiftKey"].some((n=>!!e[n]!==t[n]&&null!==e[n]))&&(e.key===t.key||e.key===t.which)}constructor(t,e){super(t,e),this.bindings={},Object.keys(this.options.bindings).forEach((t=>{this.options.bindings[t]&&this.addBinding(this.options.bindings[t])})),this.addBinding({key:"Enter",shiftKey:null},this.handleEnter),this.addBinding({key:"Enter",metaKey:null,ctrlKey:null,altKey:null},(()=>{})),/Firefox/i.test(navigator.userAgent)?(this.addBinding({key:"Backspace"},{collapsed:!0},this.handleBackspace),this.addBinding({key:"Delete"},{collapsed:!0},this.handleDelete)):(this.addBinding({key:"Backspace"},{collapsed:!0,prefix:/^.?$/},this.handleBackspace),this.addBinding({key:"Delete"},{collapsed:!0,suffix:/^.?$/},this.handleDelete)),this.addBinding({key:"Backspace"},{collapsed:!1},this.handleDeleteRange),this.addBinding({key:"Delete"},{collapsed:!1},this.handleDeleteRange),this.addBinding({key:"Backspace",altKey:null,ctrlKey:null,metaKey:null,shiftKey:null},{collapsed:!0,offset:0},this.handleBackspace),this.listen()}addBinding(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r=function(t){if("string"==typeof t||"number"==typeof t)t={key:t};else{if("object"!=typeof t)return null;t=(0,i.A)(t)}return t.shortKey&&(t[d]=t.shortKey,delete t.shortKey),t}(t);null!=r?("function"==typeof e&&(e={handler:e}),"function"==typeof n&&(n={handler:n}),(Array.isArray(r.key)?r.key:[r.key]).forEach((t=>{const i={...r,key:t,...e,...n};this.bindings[i.key]=this.bindings[i.key]||[],this.bindings[i.key].push(i)}))):h.warn("Attempted to add invalid keyboard binding",r)}listen(){this.quill.root.addEventListener("keydown",(t=>{if(t.defaultPrevented||t.isComposing)return;if(229===t.keyCode&&("Enter"===t.key||"Backspace"===t.key))return;const e=(this.bindings[t.key]||[]).concat(this.bindings[t.which]||[]).filter((e=>f.match(t,e)));if(0===e.length)return;const n=a.Ay.find(t.target,!0);if(n&&n.scroll!==this.quill.scroll)return;const i=this.quill.getSelection();if(null==i||!this.quill.hasFocus())return;const[s,o]=this.quill.getLine(i.index),[c,u]=this.quill.getLeaf(i.index),[h,d]=0===i.length?[c,u]:this.quill.getLeaf(i.index+i.length),p=c instanceof l.TextBlot?c.value().slice(0,u):"",g=h instanceof l.TextBlot?h.value().slice(d):"",m={collapsed:0===i.length,empty:0===i.length&&s.length()<=1,format:this.quill.getFormat(i),line:s,offset:o,prefix:p,suffix:g,event:t};e.some((t=>{if(null!=t.collapsed&&t.collapsed!==m.collapsed)return!1;if(null!=t.empty&&t.empty!==m.empty)return!1;if(null!=t.offset&&t.offset!==m.offset)return!1;if(Array.isArray(t.format)){if(t.format.every((t=>null==m.format[t])))return!1}else if("object"==typeof t.format&&!Object.keys(t.format).every((e=>!0===t.format[e]?null!=m.format[e]:!1===t.format[e]?null==m.format[e]:(0,r.A)(t.format[e],m.format[e]))))return!1;return!(null!=t.prefix&&!t.prefix.test(m.prefix)||null!=t.suffix&&!t.suffix.test(m.suffix)||!0===t.handler.call(this,i,m,t))}))&&t.preventDefault()}))}handleBackspace(t,e){const n=/[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test(e.prefix)?2:1;if(0===t.index||this.quill.getLength()<=1)return;let r={};const[i]=this.quill.getLine(t.index);let l=(new(o())).retain(t.index-n).delete(n);if(0===e.offset){const[e]=this.quill.getLine(t.index-1);if(e&&!("block"===e.statics.blotName&&e.length()<=1)){const e=i.formats(),n=this.quill.getFormat(t.index-1,1);if(r=s.AttributeMap.diff(e,n)||{},Object.keys(r).length>0){const e=(new(o())).retain(t.index+i.length()-2).retain(1,r);l=l.compose(e)}}}this.quill.updateContents(l,a.Ay.sources.USER),this.quill.focus()}handleDelete(t,e){const n=/^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(e.suffix)?2:1;if(t.index>=this.quill.getLength()-n)return;let r={};const[i]=this.quill.getLine(t.index);let l=(new(o())).retain(t.index).delete(n);if(e.offset>=i.length()-1){const[e]=this.quill.getLine(t.index+1);if(e){const n=i.formats(),o=this.quill.getFormat(t.index,1);r=s.AttributeMap.diff(n,o)||{},Object.keys(r).length>0&&(l=l.retain(e.length()-1).retain(1,r))}}this.quill.updateContents(l,a.Ay.sources.USER),this.quill.focus()}handleDeleteRange(t){v({range:t,quill:this.quill}),this.quill.focus()}handleEnter(t,e){const n=Object.keys(e.format).reduce(((t,n)=>(this.quill.scroll.query(n,l.Scope.BLOCK)&&!Array.isArray(e.format[n])&&(t[n]=e.format[n]),t)),{}),r=(new(o())).retain(t.index).delete(t.length).insert("\n",n);this.quill.updateContents(r,a.Ay.sources.USER),this.quill.setSelection(t.index+1,a.Ay.sources.SILENT),this.quill.focus()}}const p={bindings:{bold:b("bold"),italic:b("italic"),underline:b("underline"),indent:{key:"Tab",format:["blockquote","indent","list"],handler(t,e){return!(!e.collapsed||0===e.offset)||(this.quill.format("indent","+1",a.Ay.sources.USER),!1)}},outdent:{key:"Tab",shiftKey:!0,format:["blockquote","indent","list"],handler(t,e){return!(!e.collapsed||0===e.offset)||(this.quill.format("indent","-1",a.Ay.sources.USER),!1)}},"outdent backspace":{key:"Backspace",collapsed:!0,shiftKey:null,metaKey:null,ctrlKey:null,altKey:null,format:["indent","list"],offset:0,handler(t,e){null!=e.format.indent?this.quill.format("indent","-1",a.Ay.sources.USER):null!=e.format.list&&this.quill.format("list",!1,a.Ay.sources.USER)}},"indent code-block":g(!0),"outdent code-block":g(!1),"remove tab":{key:"Tab",shiftKey:!0,collapsed:!0,prefix:/\t$/,handler(t){this.quill.deleteText(t.index-1,1,a.Ay.sources.USER)}},tab:{key:"Tab",handler(t,e){if(e.format.table)return!0;this.quill.history.cutoff();const n=(new(o())).retain(t.index).delete(t.length).insert("\t");return this.quill.updateContents(n,a.Ay.sources.USER),this.quill.history.cutoff(),this.quill.setSelection(t.index+1,a.Ay.sources.SILENT),!1}},"blockquote empty enter":{key:"Enter",collapsed:!0,format:["blockquote"],empty:!0,handler(){this.quill.format("blockquote",!1,a.Ay.sources.USER)}},"list empty enter":{key:"Enter",collapsed:!0,format:["list"],empty:!0,handler(t,e){const n={list:!1};e.format.indent&&(n.indent=!1),this.quill.formatLine(t.index,t.length,n,a.Ay.sources.USER)}},"checklist enter":{key:"Enter",collapsed:!0,format:{list:"checked"},handler(t){const[e,n]=this.quill.getLine(t.index),r={...e.formats(),list:"checked"},i=(new(o())).retain(t.index).insert("\n",r).retain(e.length()-n-1).retain(1,{list:"unchecked"});this.quill.updateContents(i,a.Ay.sources.USER),this.quill.setSelection(t.index+1,a.Ay.sources.SILENT),this.quill.scrollSelectionIntoView()}},"header enter":{key:"Enter",collapsed:!0,format:["header"],suffix:/^$/,handler(t,e){const[n,r]=this.quill.getLine(t.index),i=(new(o())).retain(t.index).insert("\n",e.format).retain(n.length()-r-1).retain(1,{header:null});this.quill.updateContents(i,a.Ay.sources.USER),this.quill.setSelection(t.index+1,a.Ay.sources.SILENT),this.quill.scrollSelectionIntoView()}},"table backspace":{key:"Backspace",format:["table"],collapsed:!0,offset:0,handler(){}},"table delete":{key:"Delete",format:["table"],collapsed:!0,suffix:/^$/,handler(){}},"table enter":{key:"Enter",shiftKey:null,format:["table"],handler(t){const e=this.quill.getModule("table");if(e){const[n,r,i,s]=e.getTable(t),l=function(t,e,n,r){return null==e.prev&&null==e.next?null==n.prev&&null==n.next?0===r?-1:1:null==n.prev?-1:1:null==e.prev?-1:null==e.next?1:null}(0,r,i,s);if(null==l)return;let c=n.offset();if(l<0){const e=(new(o())).retain(c).insert("\n");this.quill.updateContents(e,a.Ay.sources.USER),this.quill.setSelection(t.index+1,t.length,a.Ay.sources.SILENT)}else if(l>0){c+=n.length();const t=(new(o())).retain(c).insert("\n");this.quill.updateContents(t,a.Ay.sources.USER),this.quill.setSelection(c,a.Ay.sources.USER)}}}},"table tab":{key:"Tab",shiftKey:null,format:["table"],handler(t,e){const{event:n,line:r}=e,i=r.offset(this.quill.scroll);n.shiftKey?this.quill.setSelection(i-1,a.Ay.sources.USER):this.quill.setSelection(i+r.length(),a.Ay.sources.USER)}},"list autofill":{key:" ",shiftKey:null,collapsed:!0,format:{"code-block":!1,blockquote:!1,table:!1},prefix:/^\s*?(\d+\.|-|\*|\[ ?\]|\[x\])$/,handler(t,e){if(null==this.quill.scroll.query("list"))return!0;const{length:n}=e.prefix,[r,i]=this.quill.getLine(t.index);if(i>n)return!0;let s;switch(e.prefix.trim()){case"[]":case"[ ]":s="unchecked";break;case"[x]":s="checked";break;case"-":case"*":s="bullet";break;default:s="ordered"}this.quill.insertText(t.index," ",a.Ay.sources.USER),this.quill.history.cutoff();const l=(new(o())).retain(t.index-i).delete(n+1).retain(r.length()-2-i).retain(1,{list:s});return this.quill.updateContents(l,a.Ay.sources.USER),this.quill.history.cutoff(),this.quill.setSelection(t.index-n,a.Ay.sources.SILENT),!1}},"code exit":{key:"Enter",collapsed:!0,format:["code-block"],prefix:/^$/,suffix:/^\s*$/,handler(t){const[e,n]=this.quill.getLine(t.index);let r=2,i=e;for(;null!=i&&i.length()<=1&&i.formats()["code-block"];)if(i=i.prev,r-=1,r<=0){const r=(new(o())).retain(t.index+e.length()-n-2).retain(1,{"code-block":null}).delete(1);return this.quill.updateContents(r,a.Ay.sources.USER),this.quill.setSelection(t.index-1,a.Ay.sources.SILENT),!1}return!0}},"embed left":m("ArrowLeft",!1),"embed left shift":m("ArrowLeft",!0),"embed right":m("ArrowRight",!1),"embed right shift":m("ArrowRight",!0),"table down":y(!1),"table up":y(!0)}};function g(t){return{key:"Tab",shiftKey:!t,format:{"code-block":!0},handler(e,n){let{event:r}=n;const i=this.quill.scroll.query("code-block"),{TAB:s}=i;if(0===e.length&&!r.shiftKey)return this.quill.insertText(e.index,s,a.Ay.sources.USER),void this.quill.setSelection(e.index+s.length,a.Ay.sources.SILENT);const o=0===e.length?this.quill.getLines(e.index,1):this.quill.getLines(e);let{index:l,length:c}=e;o.forEach(((e,n)=>{t?(e.insertAt(0,s),0===n?l+=s.length:c+=s.length):e.domNode.textContent.startsWith(s)&&(e.deleteAt(0,s.length),0===n?l-=s.length:c-=s.length)})),this.quill.update(a.Ay.sources.USER),this.quill.setSelection(l,c,a.Ay.sources.SILENT)}}}function m(t,e){return{key:t,shiftKey:e,altKey:null,["ArrowLeft"===t?"prefix":"suffix"]:/^$/,handler(n){let{index:r}=n;"ArrowRight"===t&&(r+=n.length+1);const[i]=this.quill.getLeaf(r);return!(i instanceof l.EmbedBlot&&("ArrowLeft"===t?e?this.quill.setSelection(n.index-1,n.length+1,a.Ay.sources.USER):this.quill.setSelection(n.index-1,a.Ay.sources.USER):e?this.quill.setSelection(n.index,n.length+1,a.Ay.sources.USER):this.quill.setSelection(n.index+n.length+1,a.Ay.sources.USER),1))}}}function b(t){return{key:t[0],shortKey:!0,handler(e,n){this.quill.format(t,!n.format[t],a.Ay.sources.USER)}}}function y(t){return{key:t?"ArrowUp":"ArrowDown",collapsed:!0,format:["table"],handler(e,n){const r=t?"prev":"next",i=n.line,s=i.parent[r];if(null!=s){if("table-row"===s.statics.blotName){let t=s.children.head,e=i;for(;null!=e.prev;)e=e.prev,t=t.next;const r=t.offset(this.quill.scroll)+Math.min(n.offset,t.length()-1);this.quill.setSelection(r,0,a.Ay.sources.USER)}}else{const e=i.table()[r];null!=e&&(t?this.quill.setSelection(e.offset(this.quill.scroll)+e.length()-1,0,a.Ay.sources.USER):this.quill.setSelection(e.offset(this.quill.scroll),0,a.Ay.sources.USER))}return!1}}}function v(t){let{quill:e,range:n}=t;const r=e.getLines(n);let i={};if(r.length>1){const t=r[0].formats(),e=r[r.length-1].formats();i=s.AttributeMap.diff(e,t)||{}}e.deleteText(n,a.Ay.sources.USER),Object.keys(i).length>0&&e.formatLine(n.index,1,i,a.Ay.sources.USER),e.setSelection(n.index,a.Ay.sources.SILENT)}f.DEFAULTS=p},8920:function(t){"use strict";var e=Object.prototype.hasOwnProperty,n="~";function r(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function s(t,e,r,s,o){if("function"!=typeof r)throw new TypeError("The listener must be a function");var l=new i(r,s||t,o),a=n?n+e:e;return t._events[a]?t._events[a].fn?t._events[a]=[t._events[a],l]:t._events[a].push(l):(t._events[a]=l,t._eventsCount++),t}function o(t,e){0==--t._eventsCount?t._events=new r:delete t._events[e]}function l(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),l.prototype.eventNames=function(){var t,r,i=[];if(0===this._eventsCount)return i;for(r in t=this._events)e.call(t,r)&&i.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},l.prototype.listeners=function(t){var e=n?n+t:t,r=this._events[e];if(!r)return[];if(r.fn)return[r.fn];for(var i=0,s=r.length,o=new Array(s);io)){var d=e.slice(0,h);if((g=e.slice(h))===c){var f=Math.min(l,h);if((b=a.slice(0,f))===(A=d.slice(0,f)))return v(b,a.slice(f),d.slice(f),c)}}if(null===u||u===l){var p=l,g=(d=e.slice(0,p),e.slice(p));if(d===a){var m=Math.min(s-p,o-p);if((y=c.slice(c.length-m))===(x=g.slice(g.length-m)))return v(a,c.slice(0,c.length-m),g.slice(0,g.length-m),y)}}}if(r.length>0&&i&&0===i.length){var b=t.slice(0,r.index),y=t.slice(r.index+r.length);if(!(o<(f=b.length)+(m=y.length))){var A=e.slice(0,f),x=e.slice(o-m);if(b===A&&y===x)return v(b,t.slice(f,s-m),e.slice(f,o-m),y)}}return null}(t,g,m);if(A)return A}var x=o(t,g),N=t.substring(0,x);x=a(t=t.substring(x),g=g.substring(x));var E=t.substring(t.length-x),w=function(t,l){var c;if(!t)return[[n,l]];if(!l)return[[e,t]];var u=t.length>l.length?t:l,h=t.length>l.length?l:t,d=u.indexOf(h);if(-1!==d)return c=[[n,u.substring(0,d)],[r,h],[n,u.substring(d+h.length)]],t.length>l.length&&(c[0][0]=c[2][0]=e),c;if(1===h.length)return[[e,t],[n,l]];var f=function(t,e){var n=t.length>e.length?t:e,r=t.length>e.length?e:t;if(n.length<4||2*r.length=t.length?[r,i,s,l,h]:null}var s,l,c,u,h,d=i(n,r,Math.ceil(n.length/4)),f=i(n,r,Math.ceil(n.length/2));return d||f?(s=f?d&&d[4].length>f[4].length?d:f:d,t.length>e.length?(l=s[0],c=s[1],u=s[2],h=s[3]):(u=s[0],h=s[1],l=s[2],c=s[3]),[l,c,u,h,s[4]]):null}(t,l);if(f){var p=f[0],g=f[1],m=f[2],b=f[3],y=f[4],v=i(p,m),A=i(g,b);return v.concat([[r,y]],A)}return function(t,r){for(var i=t.length,o=r.length,l=Math.ceil((i+o)/2),a=l,c=2*l,u=new Array(c),h=new Array(c),d=0;di)m+=2;else if(N>o)g+=2;else if(p&&(q=a+f-A)>=0&&q=(w=i-h[q]))return s(t,r,_,N)}for(var E=-v+b;E<=v-y;E+=2){for(var w,q=a+E,k=(w=E===-v||E!==v&&h[q-1]i)y+=2;else if(k>o)b+=2;else if(!p){var _;if((x=a+f-E)>=0&&x=(w=i-w))return s(t,r,_,N)}}}return[[e,t],[n,r]]}(t,l)}(t=t.substring(0,t.length-x),g=g.substring(0,g.length-x));return N&&w.unshift([r,N]),E&&w.push([r,E]),p(w,y),b&&function(t){for(var i=!1,s=[],o=0,g=null,m=0,b=0,y=0,v=0,A=0;m0?s[o-1]:-1,b=0,y=0,v=0,A=0,g=null,i=!0)),m++;for(i&&p(t),function(t){function e(t,e){if(!t||!e)return 6;var n=t.charAt(t.length-1),r=e.charAt(0),i=n.match(c),s=r.match(c),o=i&&n.match(u),l=s&&r.match(u),a=o&&n.match(h),p=l&&r.match(h),g=a&&t.match(d),m=p&&e.match(f);return g||m?5:a||p?4:i&&!o&&l?3:o||l?2:i||s?1:0}for(var n=1;n=y&&(y=v,g=i,m=s,b=o)}t[n-1][1]!=g&&(g?t[n-1][1]=g:(t.splice(n-1,1),n--),t[n][1]=m,b?t[n+1][1]=b:(t.splice(n+1,1),n--))}n++}}(t),m=1;m=w?(E>=x.length/2||E>=N.length/2)&&(t.splice(m,0,[r,N.substring(0,E)]),t[m-1][1]=x.substring(0,x.length-E),t[m+1][1]=N.substring(E),m++):(w>=x.length/2||w>=N.length/2)&&(t.splice(m,0,[r,x.substring(0,w)]),t[m-1][0]=n,t[m-1][1]=N.substring(0,N.length-w),t[m+1][0]=e,t[m+1][1]=x.substring(w),m++),m++}m++}}(w),w}function s(t,e,n,r){var s=t.substring(0,n),o=e.substring(0,r),l=t.substring(n),a=e.substring(r),c=i(s,o),u=i(l,a);return c.concat(u)}function o(t,e){if(!t||!e||t.charAt(0)!==e.charAt(0))return 0;for(var n=0,r=Math.min(t.length,e.length),i=r,s=0;nr?t=t.substring(n-r):n=0&&y(t[f][1])){var g=t[f][1].slice(-1);if(t[f][1]=t[f][1].slice(0,-1),h=g+h,d=g+d,!t[f][1]){t.splice(f,1),l--;var m=f-1;t[m]&&t[m][0]===n&&(u++,d=t[m][1]+d,m--),t[m]&&t[m][0]===e&&(c++,h=t[m][1]+h,m--),f=m}}b(t[l][1])&&(g=t[l][1].charAt(0),t[l][1]=t[l][1].slice(1),h+=g,d+=g)}if(l0||d.length>0){h.length>0&&d.length>0&&(0!==(s=o(d,h))&&(f>=0?t[f][1]+=d.substring(0,s):(t.splice(0,0,[r,d.substring(0,s)]),l++),d=d.substring(s),h=h.substring(s)),0!==(s=a(d,h))&&(t[l][1]=d.substring(d.length-s)+t[l][1],d=d.substring(0,d.length-s),h=h.substring(0,h.length-s)));var v=u+c;0===h.length&&0===d.length?(t.splice(l-v,v),l-=v):0===h.length?(t.splice(l-v,v,[n,d]),l=l-v+1):0===d.length?(t.splice(l-v,v,[e,h]),l=l-v+1):(t.splice(l-v,v,[e,h],[n,d]),l=l-v+2)}0!==l&&t[l-1][0]===r?(t[l-1][1]+=t[l][1],t.splice(l,1)):l++,u=0,c=0,h="",d=""}""===t[t.length-1][1]&&t.pop();var A=!1;for(l=1;l=55296&&t<=56319}function m(t){return t>=56320&&t<=57343}function b(t){return m(t.charCodeAt(0))}function y(t){return g(t.charCodeAt(t.length-1))}function v(t,i,s,o){return y(t)||b(o)?null:function(t){for(var e=[],n=0;n0&&e.push(t[n]);return e}([[r,t],[e,i],[n,s],[r,o]])}function A(t,e,n,r){return i(t,e,n,r,!0)}A.INSERT=n,A.DELETE=e,A.EQUAL=r,t.exports=A},9629:function(t,e,n){t=n.nmd(t);var r="__lodash_hash_undefined__",i=9007199254740991,s="[object Arguments]",o="[object Boolean]",l="[object Date]",a="[object Function]",c="[object GeneratorFunction]",u="[object Map]",h="[object Number]",d="[object Object]",f="[object Promise]",p="[object RegExp]",g="[object Set]",m="[object String]",b="[object Symbol]",y="[object WeakMap]",v="[object ArrayBuffer]",A="[object DataView]",x="[object Float32Array]",N="[object Float64Array]",E="[object Int8Array]",w="[object Int16Array]",q="[object Int32Array]",k="[object Uint8Array]",_="[object Uint8ClampedArray]",L="[object Uint16Array]",S="[object Uint32Array]",O=/\w*$/,T=/^\[object .+?Constructor\]$/,j=/^(?:0|[1-9]\d*)$/,C={};C[s]=C["[object Array]"]=C[v]=C[A]=C[o]=C[l]=C[x]=C[N]=C[E]=C[w]=C[q]=C[u]=C[h]=C[d]=C[p]=C[g]=C[m]=C[b]=C[k]=C[_]=C[L]=C[S]=!0,C["[object Error]"]=C[a]=C[y]=!1;var R="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,I="object"==typeof self&&self&&self.Object===Object&&self,B=R||I||Function("return this")(),M=e&&!e.nodeType&&e,U=M&&t&&!t.nodeType&&t,D=U&&U.exports===M;function P(t,e){return t.set(e[0],e[1]),t}function z(t,e){return t.add(e),t}function F(t,e,n,r){var i=-1,s=t?t.length:0;for(r&&s&&(n=t[++i]);++i-1},_t.prototype.set=function(t,e){var n=this.__data__,r=Tt(n,t);return r<0?n.push([t,e]):n[r][1]=e,this},Lt.prototype.clear=function(){this.__data__={hash:new kt,map:new(pt||_t),string:new kt}},Lt.prototype.delete=function(t){return It(this,t).delete(t)},Lt.prototype.get=function(t){return It(this,t).get(t)},Lt.prototype.has=function(t){return It(this,t).has(t)},Lt.prototype.set=function(t,e){return It(this,t).set(t,e),this},St.prototype.clear=function(){this.__data__=new _t},St.prototype.delete=function(t){return this.__data__.delete(t)},St.prototype.get=function(t){return this.__data__.get(t)},St.prototype.has=function(t){return this.__data__.has(t)},St.prototype.set=function(t,e){var n=this.__data__;if(n instanceof _t){var r=n.__data__;if(!pt||r.length<199)return r.push([t,e]),this;n=this.__data__=new Lt(r)}return n.set(t,e),this};var Mt=ut?V(ut,Object):function(){return[]},Ut=function(t){return et.call(t)};function Dt(t,e){return!!(e=null==e?i:e)&&("number"==typeof t||j.test(t))&&t>-1&&t%1==0&&t-1&&t%1==0&&t<=i}(t.length)&&!Kt(t)}var Vt=ht||function(){return!1};function Kt(t){var e=Wt(t)?et.call(t):"";return e==a||e==c}function Wt(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}function Zt(t){return $t(t)?function(t,e){var n=Ht(t)||function(t){return function(t){return function(t){return!!t&&"object"==typeof t}(t)&&$t(t)}(t)&&tt.call(t,"callee")&&(!at.call(t,"callee")||et.call(t)==s)}(t)?function(t,e){for(var n=-1,r=Array(t);++nc))return!1;var h=l.get(t);if(h&&l.get(e))return h==e;var d=-1,f=!0,p=n&s?new kt:void 0;for(l.set(t,e),l.set(e,t);++d-1},wt.prototype.set=function(t,e){var n=this.__data__,r=Lt(n,t);return r<0?(++this.size,n.push([t,e])):n[r][1]=e,this},qt.prototype.clear=function(){this.size=0,this.__data__={hash:new Et,map:new(ht||wt),string:new Et}},qt.prototype.delete=function(t){var e=Rt(this,t).delete(t);return this.size-=e?1:0,e},qt.prototype.get=function(t){return Rt(this,t).get(t)},qt.prototype.has=function(t){return Rt(this,t).has(t)},qt.prototype.set=function(t,e){var n=Rt(this,t),r=n.size;return n.set(t,e),this.size+=n.size==r?0:1,this},kt.prototype.add=kt.prototype.push=function(t){return this.__data__.set(t,r),this},kt.prototype.has=function(t){return this.__data__.has(t)},_t.prototype.clear=function(){this.__data__=new wt,this.size=0},_t.prototype.delete=function(t){var e=this.__data__,n=e.delete(t);return this.size=e.size,n},_t.prototype.get=function(t){return this.__data__.get(t)},_t.prototype.has=function(t){return this.__data__.has(t)},_t.prototype.set=function(t,e){var n=this.__data__;if(n instanceof wt){var r=n.__data__;if(!ht||r.length<199)return r.push([t,e]),this.size=++n.size,this;n=this.__data__=new qt(r)}return n.set(t,e),this.size=n.size,this};var Bt=lt?function(t){return null==t?[]:(t=Object(t),function(e,n){for(var r=-1,i=null==e?0:e.length,s=0,o=[];++r-1&&t%1==0&&t-1&&t%1==0&&t<=o}function Kt(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function Wt(t){return null!=t&&"object"==typeof t}var Zt=D?function(t){return function(e){return t(e)}}(D):function(t){return Wt(t)&&Vt(t.length)&&!!O[St(t)]};function Gt(t){return null!=(e=t)&&Vt(e.length)&&!$t(e)?function(t,e){var n=Ft(t),r=!n&&zt(t),i=!n&&!r&&Ht(t),s=!n&&!r&&!i&&Zt(t),o=n||r||i||s,l=o?function(t,e){for(var n=-1,r=Array(t);++n(null!=i[e]&&(t[e]=i[e]),t)),{}));for(const n in t)void 0!==t[n]&&void 0===e[n]&&(i[n]=t[n]);return Object.keys(i).length>0?i:void 0},t.diff=function(t={},e={}){"object"!=typeof t&&(t={}),"object"!=typeof e&&(e={});const n=Object.keys(t).concat(Object.keys(e)).reduce(((n,r)=>(i(t[r],e[r])||(n[r]=void 0===e[r]?null:e[r]),n)),{});return Object.keys(n).length>0?n:void 0},t.invert=function(t={},e={}){t=t||{};const n=Object.keys(e).reduce(((n,r)=>(e[r]!==t[r]&&void 0!==t[r]&&(n[r]=e[r]),n)),{});return Object.keys(t).reduce(((n,r)=>(t[r]!==e[r]&&void 0===e[r]&&(n[r]=null),n)),n)},t.transform=function(t,e,n=!1){if("object"!=typeof t)return e;if("object"!=typeof e)return;if(!n)return e;const r=Object.keys(e).reduce(((n,r)=>(void 0===t[r]&&(n[r]=e[r]),n)),{});return Object.keys(r).length>0?r:void 0}}(s||(s={})),e.default=s},5232:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.AttributeMap=e.OpIterator=e.Op=void 0;const r=n(5090),i=n(9629),s=n(4162),o=n(1270);e.AttributeMap=o.default;const l=n(4123);e.Op=l.default;const a=n(7033);e.OpIterator=a.default;const c=String.fromCharCode(0),u=(t,e)=>{if("object"!=typeof t||null===t)throw new Error("cannot retain a "+typeof t);if("object"!=typeof e||null===e)throw new Error("cannot retain a "+typeof e);const n=Object.keys(t)[0];if(!n||n!==Object.keys(e)[0])throw new Error(`embed types not matched: ${n} != ${Object.keys(e)[0]}`);return[n,t[n],e[n]]};class h{constructor(t){Array.isArray(t)?this.ops=t:null!=t&&Array.isArray(t.ops)?this.ops=t.ops:this.ops=[]}static registerEmbed(t,e){this.handlers[t]=e}static unregisterEmbed(t){delete this.handlers[t]}static getHandler(t){const e=this.handlers[t];if(!e)throw new Error(`no handlers for embed type "${t}"`);return e}insert(t,e){const n={};return"string"==typeof t&&0===t.length?this:(n.insert=t,null!=e&&"object"==typeof e&&Object.keys(e).length>0&&(n.attributes=e),this.push(n))}delete(t){return t<=0?this:this.push({delete:t})}retain(t,e){if("number"==typeof t&&t<=0)return this;const n={retain:t};return null!=e&&"object"==typeof e&&Object.keys(e).length>0&&(n.attributes=e),this.push(n)}push(t){let e=this.ops.length,n=this.ops[e-1];if(t=i(t),"object"==typeof n){if("number"==typeof t.delete&&"number"==typeof n.delete)return this.ops[e-1]={delete:n.delete+t.delete},this;if("number"==typeof n.delete&&null!=t.insert&&(e-=1,n=this.ops[e-1],"object"!=typeof n))return this.ops.unshift(t),this;if(s(t.attributes,n.attributes)){if("string"==typeof t.insert&&"string"==typeof n.insert)return this.ops[e-1]={insert:n.insert+t.insert},"object"==typeof t.attributes&&(this.ops[e-1].attributes=t.attributes),this;if("number"==typeof t.retain&&"number"==typeof n.retain)return this.ops[e-1]={retain:n.retain+t.retain},"object"==typeof t.attributes&&(this.ops[e-1].attributes=t.attributes),this}}return e===this.ops.length?this.ops.push(t):this.ops.splice(e,0,t),this}chop(){const t=this.ops[this.ops.length-1];return t&&"number"==typeof t.retain&&!t.attributes&&this.ops.pop(),this}filter(t){return this.ops.filter(t)}forEach(t){this.ops.forEach(t)}map(t){return this.ops.map(t)}partition(t){const e=[],n=[];return this.forEach((r=>{(t(r)?e:n).push(r)})),[e,n]}reduce(t,e){return this.ops.reduce(t,e)}changeLength(){return this.reduce(((t,e)=>e.insert?t+l.default.length(e):e.delete?t-e.delete:t),0)}length(){return this.reduce(((t,e)=>t+l.default.length(e)),0)}slice(t=0,e=1/0){const n=[],r=new a.default(this.ops);let i=0;for(;i0&&n.next(i.retain-t)}const l=new h(r);for(;e.hasNext()||n.hasNext();)if("insert"===n.peekType())l.push(n.next());else if("delete"===e.peekType())l.push(e.next());else{const t=Math.min(e.peekLength(),n.peekLength()),r=e.next(t),i=n.next(t);if(i.retain){const a={};if("number"==typeof r.retain)a.retain="number"==typeof i.retain?t:i.retain;else if("number"==typeof i.retain)null==r.retain?a.insert=r.insert:a.retain=r.retain;else{const t=null==r.retain?"insert":"retain",[e,n,s]=u(r[t],i.retain),o=h.getHandler(e);a[t]={[e]:o.compose(n,s,"retain"===t)}}const c=o.default.compose(r.attributes,i.attributes,"number"==typeof r.retain);if(c&&(a.attributes=c),l.push(a),!n.hasNext()&&s(l.ops[l.ops.length-1],a)){const t=new h(e.rest());return l.concat(t).chop()}}else"number"==typeof i.delete&&("number"==typeof r.retain||"object"==typeof r.retain&&null!==r.retain)&&l.push(i)}return l.chop()}concat(t){const e=new h(this.ops.slice());return t.ops.length>0&&(e.push(t.ops[0]),e.ops=e.ops.concat(t.ops.slice(1))),e}diff(t,e){if(this.ops===t.ops)return new h;const n=[this,t].map((e=>e.map((n=>{if(null!=n.insert)return"string"==typeof n.insert?n.insert:c;throw new Error("diff() called "+(e===t?"on":"with")+" non-document")})).join(""))),i=new h,l=r(n[0],n[1],e,!0),u=new a.default(this.ops),d=new a.default(t.ops);return l.forEach((t=>{let e=t[1].length;for(;e>0;){let n=0;switch(t[0]){case r.INSERT:n=Math.min(d.peekLength(),e),i.push(d.next(n));break;case r.DELETE:n=Math.min(e,u.peekLength()),u.next(n),i.delete(n);break;case r.EQUAL:n=Math.min(u.peekLength(),d.peekLength(),e);const t=u.next(n),l=d.next(n);s(t.insert,l.insert)?i.retain(n,o.default.diff(t.attributes,l.attributes)):i.push(l).delete(n)}e-=n}})),i.chop()}eachLine(t,e="\n"){const n=new a.default(this.ops);let r=new h,i=0;for(;n.hasNext();){if("insert"!==n.peekType())return;const s=n.peek(),o=l.default.length(s)-n.peekLength(),a="string"==typeof s.insert?s.insert.indexOf(e,o)-o:-1;if(a<0)r.push(n.next());else if(a>0)r.push(n.next(a));else{if(!1===t(r,n.next(1).attributes||{},i))return;i+=1,r=new h}}r.length()>0&&t(r,{},i)}invert(t){const e=new h;return this.reduce(((n,r)=>{if(r.insert)e.delete(l.default.length(r));else{if("number"==typeof r.retain&&null==r.attributes)return e.retain(r.retain),n+r.retain;if(r.delete||"number"==typeof r.retain){const i=r.delete||r.retain;return t.slice(n,n+i).forEach((t=>{r.delete?e.push(t):r.retain&&r.attributes&&e.retain(l.default.length(t),o.default.invert(r.attributes,t.attributes))})),n+i}if("object"==typeof r.retain&&null!==r.retain){const i=t.slice(n,n+1),s=new a.default(i.ops).next(),[l,c,d]=u(r.retain,s.insert),f=h.getHandler(l);return e.retain({[l]:f.invert(c,d)},o.default.invert(r.attributes,s.attributes)),n+1}}return n}),0),e.chop()}transform(t,e=!1){if(e=!!e,"number"==typeof t)return this.transformPosition(t,e);const n=t,r=new a.default(this.ops),i=new a.default(n.ops),s=new h;for(;r.hasNext()||i.hasNext();)if("insert"!==r.peekType()||!e&&"insert"===i.peekType())if("insert"===i.peekType())s.push(i.next());else{const t=Math.min(r.peekLength(),i.peekLength()),n=r.next(t),l=i.next(t);if(n.delete)continue;if(l.delete)s.push(l);else{const r=n.retain,i=l.retain;let a="object"==typeof i&&null!==i?i:t;if("object"==typeof r&&null!==r&&"object"==typeof i&&null!==i){const t=Object.keys(r)[0];if(t===Object.keys(i)[0]){const n=h.getHandler(t);n&&(a={[t]:n.transform(r[t],i[t],e)})}}s.retain(a,o.default.transform(n.attributes,l.attributes,e))}}else s.retain(l.default.length(r.next()));return s.chop()}transformPosition(t,e=!1){e=!!e;const n=new a.default(this.ops);let r=0;for(;n.hasNext()&&r<=t;){const i=n.peekLength(),s=n.peekType();n.next(),"delete"!==s?("insert"===s&&(r=i-n?(t=i-n,this.index+=1,this.offset=0):this.offset+=t,"number"==typeof e.delete)return{delete:t};{const r={};return e.attributes&&(r.attributes=e.attributes),"number"==typeof e.retain?r.retain=t:"object"==typeof e.retain&&null!==e.retain?r.retain=e.retain:"string"==typeof e.insert?r.insert=e.insert.substr(n,t):r.insert=e.insert,r}}return{retain:1/0}}peek(){return this.ops[this.index]}peekLength(){return this.ops[this.index]?r.default.length(this.ops[this.index])-this.offset:1/0}peekType(){const t=this.ops[this.index];return t?"number"==typeof t.delete?"delete":"number"==typeof t.retain||"object"==typeof t.retain&&null!==t.retain?"retain":"insert":"retain"}rest(){if(this.hasNext()){if(0===this.offset)return this.ops.slice(this.index);{const t=this.offset,e=this.index,n=this.next(),r=this.ops.slice(this.index);return this.offset=t,this.index=e,[n].concat(r)}}return[]}}},8820:function(t,e,n){"use strict";n.d(e,{A:function(){return l}});var r=n(8138),i=function(t,e){for(var n=t.length;n--;)if((0,r.A)(t[n][0],e))return n;return-1},s=Array.prototype.splice;function o(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1},o.prototype.set=function(t,e){var n=this.__data__,r=i(n,t);return r<0?(++this.size,n.push([t,e])):n[r][1]=e,this};var l=o},2461:function(t,e,n){"use strict";var r=n(2281),i=n(5507),s=(0,r.A)(i.A,"Map");e.A=s},3558:function(t,e,n){"use strict";n.d(e,{A:function(){return d}});var r=(0,n(2281).A)(Object,"create"),i=Object.prototype.hasOwnProperty,s=Object.prototype.hasOwnProperty;function o(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&tc))return!1;var h=s.get(t),d=s.get(e);if(h&&d)return h==e&&d==t;var f=-1,p=!0,g=2&n?new o:void 0;for(s.set(t,e),s.set(e,t);++f-1&&t%1==0&&t<=9007199254740991}},659:function(t,e){"use strict";e.A=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},7948:function(t,e){"use strict";e.A=function(t){return null!=t&&"object"==typeof t}},5755:function(t,e,n){"use strict";n.d(e,{A:function(){return u}});var r=n(2159),i=n(1628),s=n(7948),o={};o["[object Float32Array]"]=o["[object Float64Array]"]=o["[object Int8Array]"]=o["[object Int16Array]"]=o["[object Int32Array]"]=o["[object Uint8Array]"]=o["[object Uint8ClampedArray]"]=o["[object Uint16Array]"]=o["[object Uint32Array]"]=!0,o["[object Arguments]"]=o["[object Array]"]=o["[object ArrayBuffer]"]=o["[object Boolean]"]=o["[object DataView]"]=o["[object Date]"]=o["[object Error]"]=o["[object Function]"]=o["[object Map]"]=o["[object Number]"]=o["[object Object]"]=o["[object RegExp]"]=o["[object Set]"]=o["[object String]"]=o["[object WeakMap]"]=!1;var l=n(5771),a=n(8795),c=a.A&&a.A.isTypedArray,u=c?(0,l.A)(c):function(t){return(0,s.A)(t)&&(0,i.A)(t.length)&&!!o[(0,r.A)(t)]}},3169:function(t,e,n){"use strict";n.d(e,{A:function(){return a}});var r=n(6753),i=n(501),s=(0,n(2217).A)(Object.keys,Object),o=Object.prototype.hasOwnProperty,l=n(3628),a=function(t){return(0,l.A)(t)?(0,r.A)(t):function(t){if(!(0,i.A)(t))return s(t);var e=[];for(var n in Object(t))o.call(t,n)&&"constructor"!=n&&e.push(n);return e}(t)}},2624:function(t,e,n){"use strict";n.d(e,{A:function(){return c}});var r=n(6753),i=n(659),s=n(501),o=Object.prototype.hasOwnProperty,l=function(t){if(!(0,i.A)(t))return function(t){var e=[];if(null!=t)for(var n in Object(t))e.push(n);return e}(t);var e=(0,s.A)(t),n=[];for(var r in t)("constructor"!=r||!e&&o.call(t,r))&&n.push(r);return n},a=n(3628),c=function(t){return(0,a.A)(t)?(0,r.A)(t,!0):l(t)}},8347:function(t,e,n){"use strict";n.d(e,{A:function(){return $}});var r,i,s,o,l=n(2673),a=n(6770),c=n(8138),u=function(t,e,n){(void 0!==n&&!(0,c.A)(t[e],n)||void 0===n&&!(e in t))&&(0,a.A)(t,e,n)},h=function(t,e,n){for(var r=-1,i=Object(t),s=n(t),o=s.length;o--;){var l=s[++r];if(!1===e(i[l],l,i))break}return t},d=n(3812),f=n(1827),p=n(4405),g=n(1683),m=n(8412),b=n(723),y=n(3628),v=n(7948),A=n(776),x=n(7572),N=n(659),E=n(2159),w=n(8769),q=Function.prototype,k=Object.prototype,_=q.toString,L=k.hasOwnProperty,S=_.call(Object),O=n(5755),T=function(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]},j=n(9601),C=n(2624),R=function(t,e,n,r,i,s,o){var l,a=T(t,n),c=T(e,n),h=o.get(c);if(h)u(t,n,h);else{var q=s?s(a,c,n+"",t,e,o):void 0,k=void 0===q;if(k){var R=(0,b.A)(c),I=!R&&(0,A.A)(c),B=!R&&!I&&(0,O.A)(c);q=c,R||I||B?(0,b.A)(a)?q=a:(l=a,(0,v.A)(l)&&(0,y.A)(l)?q=(0,p.A)(a):I?(k=!1,q=(0,d.A)(c,!0)):B?(k=!1,q=(0,f.A)(c,!0)):q=[]):function(t){if(!(0,v.A)(t)||"[object Object]"!=(0,E.A)(t))return!1;var e=(0,w.A)(t);if(null===e)return!0;var n=L.call(e,"constructor")&&e.constructor;return"function"==typeof n&&n instanceof n&&_.call(n)==S}(c)||(0,m.A)(c)?(q=a,(0,m.A)(a)?q=function(t){return(0,j.A)(t,(0,C.A)(t))}(a):(0,N.A)(a)&&!(0,x.A)(a)||(q=(0,g.A)(c))):k=!1}k&&(o.set(c,q),i(q,c,r,s,o),o.delete(c)),u(t,n,q)}},I=function t(e,n,r,i,s){e!==n&&h(n,(function(o,a){if(s||(s=new l.A),(0,N.A)(o))R(e,n,a,r,t,i,s);else{var c=i?i(T(e,a),o,a+"",e,n,s):void 0;void 0===c&&(c=o),u(e,a,c)}}),C.A)},B=function(t){return t},M=Math.max,U=n(7889),D=U.A?function(t,e){return(0,U.A)(t,"toString",{configurable:!0,enumerable:!1,value:(n=e,function(){return n}),writable:!0});var n}:B,P=Date.now,z=(r=D,i=0,s=0,function(){var t=P(),e=16-(t-s);if(s=t,e>0){if(++i>=800)return arguments[0]}else i=0;return r.apply(void 0,arguments)}),F=function(t,e){return z(function(t,e,n){return e=M(void 0===e?t.length-1:e,0),function(){for(var r=arguments,i=-1,s=M(r.length-e,0),o=Array(s);++i1?e[r-1]:void 0,s=r>2?e[2]:void 0;for(i=o.length>3&&"function"==typeof i?(r--,i):void 0,s&&function(t,e,n){if(!(0,N.A)(n))return!1;var r=typeof e;return!!("number"==r?(0,y.A)(n)&&(0,H.A)(e,n.length):"string"==r&&e in n)&&(0,c.A)(n[e],t)}(e[0],e[1],s)&&(i=r<3?void 0:i,r=1),t=Object(t);++n(t[t.TYPE=3]="TYPE",t[t.LEVEL=12]="LEVEL",t[t.ATTRIBUTE=13]="ATTRIBUTE",t[t.BLOT=14]="BLOT",t[t.INLINE=7]="INLINE",t[t.BLOCK=11]="BLOCK",t[t.BLOCK_BLOT=10]="BLOCK_BLOT",t[t.INLINE_BLOT=6]="INLINE_BLOT",t[t.BLOCK_ATTRIBUTE=9]="BLOCK_ATTRIBUTE",t[t.INLINE_ATTRIBUTE=5]="INLINE_ATTRIBUTE",t[t.ANY=15]="ANY",t))(r||{});class i{constructor(t,e,n={}){this.attrName=t,this.keyName=e;const i=r.TYPE&r.ATTRIBUTE;this.scope=null!=n.scope?n.scope&r.LEVEL|i:r.ATTRIBUTE,null!=n.whitelist&&(this.whitelist=n.whitelist)}static keys(t){return Array.from(t.attributes).map((t=>t.name))}add(t,e){return!!this.canAdd(t,e)&&(t.setAttribute(this.keyName,e),!0)}canAdd(t,e){return null==this.whitelist||("string"==typeof e?this.whitelist.indexOf(e.replace(/["']/g,""))>-1:this.whitelist.indexOf(e)>-1)}remove(t){t.removeAttribute(this.keyName)}value(t){const e=t.getAttribute(this.keyName);return this.canAdd(t,e)&&e?e:""}}class s extends Error{constructor(t){super(t="[Parchment] "+t),this.message=t,this.name=this.constructor.name}}const o=class t{constructor(){this.attributes={},this.classes={},this.tags={},this.types={}}static find(t,e=!1){if(null==t)return null;if(this.blots.has(t))return this.blots.get(t)||null;if(e){let n=null;try{n=t.parentNode}catch{return null}return this.find(n,e)}return null}create(e,n,r){const i=this.query(n);if(null==i)throw new s(`Unable to create ${n} blot`);const o=i,l=n instanceof Node||n.nodeType===Node.TEXT_NODE?n:o.create(r),a=new o(e,l,r);return t.blots.set(a.domNode,a),a}find(e,n=!1){return t.find(e,n)}query(t,e=r.ANY){let n;return"string"==typeof t?n=this.types[t]||this.attributes[t]:t instanceof Text||t.nodeType===Node.TEXT_NODE?n=this.types.text:"number"==typeof t?t&r.LEVEL&r.BLOCK?n=this.types.block:t&r.LEVEL&r.INLINE&&(n=this.types.inline):t instanceof Element&&((t.getAttribute("class")||"").split(/\s+/).some((t=>(n=this.classes[t],!!n))),n=n||this.tags[t.tagName]),null==n?null:"scope"in n&&e&r.LEVEL&n.scope&&e&r.TYPE&n.scope?n:null}register(...t){return t.map((t=>{const e="blotName"in t,n="attrName"in t;if(!e&&!n)throw new s("Invalid definition");if(e&&"abstract"===t.blotName)throw new s("Cannot register abstract class");const r=e?t.blotName:n?t.attrName:void 0;return this.types[r]=t,n?"string"==typeof t.keyName&&(this.attributes[t.keyName]=t):e&&(t.className&&(this.classes[t.className]=t),t.tagName&&(Array.isArray(t.tagName)?t.tagName=t.tagName.map((t=>t.toUpperCase())):t.tagName=t.tagName.toUpperCase(),(Array.isArray(t.tagName)?t.tagName:[t.tagName]).forEach((e=>{(null==this.tags[e]||null==t.className)&&(this.tags[e]=t)})))),t}))}};o.blots=new WeakMap;let l=o;function a(t,e){return(t.getAttribute("class")||"").split(/\s+/).filter((t=>0===t.indexOf(`${e}-`)))}const c=class extends i{static keys(t){return(t.getAttribute("class")||"").split(/\s+/).map((t=>t.split("-").slice(0,-1).join("-")))}add(t,e){return!!this.canAdd(t,e)&&(this.remove(t),t.classList.add(`${this.keyName}-${e}`),!0)}remove(t){a(t,this.keyName).forEach((e=>{t.classList.remove(e)})),0===t.classList.length&&t.removeAttribute("class")}value(t){const e=(a(t,this.keyName)[0]||"").slice(this.keyName.length+1);return this.canAdd(t,e)?e:""}};function u(t){const e=t.split("-"),n=e.slice(1).map((t=>t[0].toUpperCase()+t.slice(1))).join("");return e[0]+n}const h=class extends i{static keys(t){return(t.getAttribute("style")||"").split(";").map((t=>t.split(":")[0].trim()))}add(t,e){return!!this.canAdd(t,e)&&(t.style[u(this.keyName)]=e,!0)}remove(t){t.style[u(this.keyName)]="",t.getAttribute("style")||t.removeAttribute("style")}value(t){const e=t.style[u(this.keyName)];return this.canAdd(t,e)?e:""}},d=class{constructor(t){this.attributes={},this.domNode=t,this.build()}attribute(t,e){e?t.add(this.domNode,e)&&(null!=t.value(this.domNode)?this.attributes[t.attrName]=t:delete this.attributes[t.attrName]):(t.remove(this.domNode),delete this.attributes[t.attrName])}build(){this.attributes={};const t=l.find(this.domNode);if(null==t)return;const e=i.keys(this.domNode),n=c.keys(this.domNode),s=h.keys(this.domNode);e.concat(n).concat(s).forEach((e=>{const n=t.scroll.query(e,r.ATTRIBUTE);n instanceof i&&(this.attributes[n.attrName]=n)}))}copy(t){Object.keys(this.attributes).forEach((e=>{const n=this.attributes[e].value(this.domNode);t.format(e,n)}))}move(t){this.copy(t),Object.keys(this.attributes).forEach((t=>{this.attributes[t].remove(this.domNode)})),this.attributes={}}values(){return Object.keys(this.attributes).reduce(((t,e)=>(t[e]=this.attributes[e].value(this.domNode),t)),{})}},f=class{constructor(t,e){this.scroll=t,this.domNode=e,l.blots.set(e,this),this.prev=null,this.next=null}static create(t){if(null==this.tagName)throw new s("Blot definition missing tagName");let e,n;return Array.isArray(this.tagName)?("string"==typeof t?(n=t.toUpperCase(),parseInt(n,10).toString()===n&&(n=parseInt(n,10))):"number"==typeof t&&(n=t),e="number"==typeof n?document.createElement(this.tagName[n-1]):n&&this.tagName.indexOf(n)>-1?document.createElement(n):document.createElement(this.tagName[0])):e=document.createElement(this.tagName),this.className&&e.classList.add(this.className),e}get statics(){return this.constructor}attach(){}clone(){const t=this.domNode.cloneNode(!1);return this.scroll.create(t)}detach(){null!=this.parent&&this.parent.removeChild(this),l.blots.delete(this.domNode)}deleteAt(t,e){this.isolate(t,e).remove()}formatAt(t,e,n,i){const s=this.isolate(t,e);if(null!=this.scroll.query(n,r.BLOT)&&i)s.wrap(n,i);else if(null!=this.scroll.query(n,r.ATTRIBUTE)){const t=this.scroll.create(this.statics.scope);s.wrap(t),t.format(n,i)}}insertAt(t,e,n){const r=null==n?this.scroll.create("text",e):this.scroll.create(e,n),i=this.split(t);this.parent.insertBefore(r,i||void 0)}isolate(t,e){const n=this.split(t);if(null==n)throw new Error("Attempt to isolate at end");return n.split(e),n}length(){return 1}offset(t=this.parent){return null==this.parent||this===t?0:this.parent.children.offset(this)+this.parent.offset(t)}optimize(t){this.statics.requiredContainer&&!(this.parent instanceof this.statics.requiredContainer)&&this.wrap(this.statics.requiredContainer.blotName)}remove(){null!=this.domNode.parentNode&&this.domNode.parentNode.removeChild(this.domNode),this.detach()}replaceWith(t,e){const n="string"==typeof t?this.scroll.create(t,e):t;return null!=this.parent&&(this.parent.insertBefore(n,this.next||void 0),this.remove()),n}split(t,e){return 0===t?this:this.next}update(t,e){}wrap(t,e){const n="string"==typeof t?this.scroll.create(t,e):t;if(null!=this.parent&&this.parent.insertBefore(n,this.next||void 0),"function"!=typeof n.appendChild)throw new s(`Cannot wrap ${t}`);return n.appendChild(this),n}};f.blotName="abstract";let p=f;const g=class extends p{static value(t){return!0}index(t,e){return this.domNode===t||this.domNode.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_CONTAINED_BY?Math.min(e,1):-1}position(t,e){let n=Array.from(this.parent.domNode.childNodes).indexOf(this.domNode);return t>0&&(n+=1),[this.parent.domNode,n]}value(){return{[this.statics.blotName]:this.statics.value(this.domNode)||!0}}};g.scope=r.INLINE_BLOT;const m=g;class b{constructor(){this.head=null,this.tail=null,this.length=0}append(...t){if(this.insertBefore(t[0],null),t.length>1){const e=t.slice(1);this.append(...e)}}at(t){const e=this.iterator();let n=e();for(;n&&t>0;)t-=1,n=e();return n}contains(t){const e=this.iterator();let n=e();for(;n;){if(n===t)return!0;n=e()}return!1}indexOf(t){const e=this.iterator();let n=e(),r=0;for(;n;){if(n===t)return r;r+=1,n=e()}return-1}insertBefore(t,e){null!=t&&(this.remove(t),t.next=e,null!=e?(t.prev=e.prev,null!=e.prev&&(e.prev.next=t),e.prev=t,e===this.head&&(this.head=t)):null!=this.tail?(this.tail.next=t,t.prev=this.tail,this.tail=t):(t.prev=null,this.head=this.tail=t),this.length+=1)}offset(t){let e=0,n=this.head;for(;null!=n;){if(n===t)return e;e+=n.length(),n=n.next}return-1}remove(t){this.contains(t)&&(null!=t.prev&&(t.prev.next=t.next),null!=t.next&&(t.next.prev=t.prev),t===this.head&&(this.head=t.next),t===this.tail&&(this.tail=t.prev),this.length-=1)}iterator(t=this.head){return()=>{const e=t;return null!=t&&(t=t.next),e}}find(t,e=!1){const n=this.iterator();let r=n();for(;r;){const i=r.length();if(ts?n(l,t-s,Math.min(e,s+r-t)):n(l,0,Math.min(r,t+e-s)),s+=r,l=o()}}map(t){return this.reduce(((e,n)=>(e.push(t(n)),e)),[])}reduce(t,e){const n=this.iterator();let r=n();for(;r;)e=t(e,r),r=n();return e}}function y(t,e){const n=e.find(t);if(n)return n;try{return e.create(t)}catch{const n=e.create(r.INLINE);return Array.from(t.childNodes).forEach((t=>{n.domNode.appendChild(t)})),t.parentNode&&t.parentNode.replaceChild(n.domNode,t),n.attach(),n}}const v=class t extends p{constructor(t,e){super(t,e),this.uiNode=null,this.build()}appendChild(t){this.insertBefore(t)}attach(){super.attach(),this.children.forEach((t=>{t.attach()}))}attachUI(e){null!=this.uiNode&&this.uiNode.remove(),this.uiNode=e,t.uiClass&&this.uiNode.classList.add(t.uiClass),this.uiNode.setAttribute("contenteditable","false"),this.domNode.insertBefore(this.uiNode,this.domNode.firstChild)}build(){this.children=new b,Array.from(this.domNode.childNodes).filter((t=>t!==this.uiNode)).reverse().forEach((t=>{try{const e=y(t,this.scroll);this.insertBefore(e,this.children.head||void 0)}catch(t){if(t instanceof s)return;throw t}}))}deleteAt(t,e){if(0===t&&e===this.length())return this.remove();this.children.forEachAt(t,e,((t,e,n)=>{t.deleteAt(e,n)}))}descendant(e,n=0){const[r,i]=this.children.find(n);return null==e.blotName&&e(r)||null!=e.blotName&&r instanceof e?[r,i]:r instanceof t?r.descendant(e,i):[null,-1]}descendants(e,n=0,r=Number.MAX_VALUE){let i=[],s=r;return this.children.forEachAt(n,r,((n,r,o)=>{(null==e.blotName&&e(n)||null!=e.blotName&&n instanceof e)&&i.push(n),n instanceof t&&(i=i.concat(n.descendants(e,r,s))),s-=o})),i}detach(){this.children.forEach((t=>{t.detach()})),super.detach()}enforceAllowedChildren(){let e=!1;this.children.forEach((n=>{e||this.statics.allowedChildren.some((t=>n instanceof t))||(n.statics.scope===r.BLOCK_BLOT?(null!=n.next&&this.splitAfter(n),null!=n.prev&&this.splitAfter(n.prev),n.parent.unwrap(),e=!0):n instanceof t?n.unwrap():n.remove())}))}formatAt(t,e,n,r){this.children.forEachAt(t,e,((t,e,i)=>{t.formatAt(e,i,n,r)}))}insertAt(t,e,n){const[r,i]=this.children.find(t);if(r)r.insertAt(i,e,n);else{const t=null==n?this.scroll.create("text",e):this.scroll.create(e,n);this.appendChild(t)}}insertBefore(t,e){null!=t.parent&&t.parent.children.remove(t);let n=null;this.children.insertBefore(t,e||null),t.parent=this,null!=e&&(n=e.domNode),(this.domNode.parentNode!==t.domNode||this.domNode.nextSibling!==n)&&this.domNode.insertBefore(t.domNode,n),t.attach()}length(){return this.children.reduce(((t,e)=>t+e.length()),0)}moveChildren(t,e){this.children.forEach((n=>{t.insertBefore(n,e)}))}optimize(t){if(super.optimize(t),this.enforceAllowedChildren(),null!=this.uiNode&&this.uiNode!==this.domNode.firstChild&&this.domNode.insertBefore(this.uiNode,this.domNode.firstChild),0===this.children.length)if(null!=this.statics.defaultChild){const t=this.scroll.create(this.statics.defaultChild.blotName);this.appendChild(t)}else this.remove()}path(e,n=!1){const[r,i]=this.children.find(e,n),s=[[this,e]];return r instanceof t?s.concat(r.path(i,n)):(null!=r&&s.push([r,i]),s)}removeChild(t){this.children.remove(t)}replaceWith(e,n){const r="string"==typeof e?this.scroll.create(e,n):e;return r instanceof t&&this.moveChildren(r),super.replaceWith(r)}split(t,e=!1){if(!e){if(0===t)return this;if(t===this.length())return this.next}const n=this.clone();return this.parent&&this.parent.insertBefore(n,this.next||void 0),this.children.forEachAt(t,this.length(),((t,r,i)=>{const s=t.split(r,e);null!=s&&n.appendChild(s)})),n}splitAfter(t){const e=this.clone();for(;null!=t.next;)e.appendChild(t.next);return this.parent&&this.parent.insertBefore(e,this.next||void 0),e}unwrap(){this.parent&&this.moveChildren(this.parent,this.next||void 0),this.remove()}update(t,e){const n=[],r=[];t.forEach((t=>{t.target===this.domNode&&"childList"===t.type&&(n.push(...t.addedNodes),r.push(...t.removedNodes))})),r.forEach((t=>{if(null!=t.parentNode&&"IFRAME"!==t.tagName&&document.body.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_CONTAINED_BY)return;const e=this.scroll.find(t);null!=e&&(null==e.domNode.parentNode||e.domNode.parentNode===this.domNode)&&e.detach()})),n.filter((t=>t.parentNode===this.domNode&&t!==this.uiNode)).sort(((t,e)=>t===e?0:t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING?1:-1)).forEach((t=>{let e=null;null!=t.nextSibling&&(e=this.scroll.find(t.nextSibling));const n=y(t,this.scroll);(n.next!==e||null==n.next)&&(null!=n.parent&&n.parent.removeChild(this),this.insertBefore(n,e||void 0))})),this.enforceAllowedChildren()}};v.uiClass="";const A=v,x=class t extends A{static create(t){return super.create(t)}static formats(e,n){const r=n.query(t.blotName);if(null==r||e.tagName!==r.tagName){if("string"==typeof this.tagName)return!0;if(Array.isArray(this.tagName))return e.tagName.toLowerCase()}}constructor(t,e){super(t,e),this.attributes=new d(this.domNode)}format(e,n){if(e!==this.statics.blotName||n){const t=this.scroll.query(e,r.INLINE);if(null==t)return;t instanceof i?this.attributes.attribute(t,n):n&&(e!==this.statics.blotName||this.formats()[e]!==n)&&this.replaceWith(e,n)}else this.children.forEach((e=>{e instanceof t||(e=e.wrap(t.blotName,!0)),this.attributes.copy(e)})),this.unwrap()}formats(){const t=this.attributes.values(),e=this.statics.formats(this.domNode,this.scroll);return null!=e&&(t[this.statics.blotName]=e),t}formatAt(t,e,n,i){null!=this.formats()[n]||this.scroll.query(n,r.ATTRIBUTE)?this.isolate(t,e).format(n,i):super.formatAt(t,e,n,i)}optimize(e){super.optimize(e);const n=this.formats();if(0===Object.keys(n).length)return this.unwrap();const r=this.next;r instanceof t&&r.prev===this&&function(t,e){if(Object.keys(t).length!==Object.keys(e).length)return!1;for(const n in t)if(t[n]!==e[n])return!1;return!0}(n,r.formats())&&(r.moveChildren(this),r.remove())}replaceWith(t,e){const n=super.replaceWith(t,e);return this.attributes.copy(n),n}update(t,e){super.update(t,e),t.some((t=>t.target===this.domNode&&"attributes"===t.type))&&this.attributes.build()}wrap(e,n){const r=super.wrap(e,n);return r instanceof t&&this.attributes.move(r),r}};x.allowedChildren=[x,m],x.blotName="inline",x.scope=r.INLINE_BLOT,x.tagName="SPAN";const N=x,E=class t extends A{static create(t){return super.create(t)}static formats(e,n){const r=n.query(t.blotName);if(null==r||e.tagName!==r.tagName){if("string"==typeof this.tagName)return!0;if(Array.isArray(this.tagName))return e.tagName.toLowerCase()}}constructor(t,e){super(t,e),this.attributes=new d(this.domNode)}format(e,n){const s=this.scroll.query(e,r.BLOCK);null!=s&&(s instanceof i?this.attributes.attribute(s,n):e!==this.statics.blotName||n?n&&(e!==this.statics.blotName||this.formats()[e]!==n)&&this.replaceWith(e,n):this.replaceWith(t.blotName))}formats(){const t=this.attributes.values(),e=this.statics.formats(this.domNode,this.scroll);return null!=e&&(t[this.statics.blotName]=e),t}formatAt(t,e,n,i){null!=this.scroll.query(n,r.BLOCK)?this.format(n,i):super.formatAt(t,e,n,i)}insertAt(t,e,n){if(null==n||null!=this.scroll.query(e,r.INLINE))super.insertAt(t,e,n);else{const r=this.split(t);if(null==r)throw new Error("Attempt to insertAt after block boundaries");{const t=this.scroll.create(e,n);r.parent.insertBefore(t,r)}}}replaceWith(t,e){const n=super.replaceWith(t,e);return this.attributes.copy(n),n}update(t,e){super.update(t,e),t.some((t=>t.target===this.domNode&&"attributes"===t.type))&&this.attributes.build()}};E.blotName="block",E.scope=r.BLOCK_BLOT,E.tagName="P",E.allowedChildren=[N,E,m];const w=E,q=class extends A{checkMerge(){return null!==this.next&&this.next.statics.blotName===this.statics.blotName}deleteAt(t,e){super.deleteAt(t,e),this.enforceAllowedChildren()}formatAt(t,e,n,r){super.formatAt(t,e,n,r),this.enforceAllowedChildren()}insertAt(t,e,n){super.insertAt(t,e,n),this.enforceAllowedChildren()}optimize(t){super.optimize(t),this.children.length>0&&null!=this.next&&this.checkMerge()&&(this.next.moveChildren(this),this.next.remove())}};q.blotName="container",q.scope=r.BLOCK_BLOT;const k=q,_=class extends m{static formats(t,e){}format(t,e){super.formatAt(0,this.length(),t,e)}formatAt(t,e,n,r){0===t&&e===this.length()?this.format(n,r):super.formatAt(t,e,n,r)}formats(){return this.statics.formats(this.domNode,this.scroll)}},L={attributes:!0,characterData:!0,characterDataOldValue:!0,childList:!0,subtree:!0},S=class extends A{constructor(t,e){super(null,e),this.registry=t,this.scroll=this,this.build(),this.observer=new MutationObserver((t=>{this.update(t)})),this.observer.observe(this.domNode,L),this.attach()}create(t,e){return this.registry.create(this,t,e)}find(t,e=!1){const n=this.registry.find(t,e);return n?n.scroll===this?n:e?this.find(n.scroll.domNode.parentNode,!0):null:null}query(t,e=r.ANY){return this.registry.query(t,e)}register(...t){return this.registry.register(...t)}build(){null!=this.scroll&&super.build()}detach(){super.detach(),this.observer.disconnect()}deleteAt(t,e){this.update(),0===t&&e===this.length()?this.children.forEach((t=>{t.remove()})):super.deleteAt(t,e)}formatAt(t,e,n,r){this.update(),super.formatAt(t,e,n,r)}insertAt(t,e,n){this.update(),super.insertAt(t,e,n)}optimize(t=[],e={}){super.optimize(e);const n=e.mutationsMap||new WeakMap;let r=Array.from(this.observer.takeRecords());for(;r.length>0;)t.push(r.pop());const i=(t,e=!0)=>{null==t||t===this||null!=t.domNode.parentNode&&(n.has(t.domNode)||n.set(t.domNode,[]),e&&i(t.parent))},s=t=>{n.has(t.domNode)&&(t instanceof A&&t.children.forEach(s),n.delete(t.domNode),t.optimize(e))};let o=t;for(let e=0;o.length>0;e+=1){if(e>=100)throw new Error("[Parchment] Maximum optimize iterations reached");for(o.forEach((t=>{const e=this.find(t.target,!0);null!=e&&(e.domNode===t.target&&("childList"===t.type?(i(this.find(t.previousSibling,!1)),Array.from(t.addedNodes).forEach((t=>{const e=this.find(t,!1);i(e,!1),e instanceof A&&e.children.forEach((t=>{i(t,!1)}))}))):"attributes"===t.type&&i(e.prev)),i(e))})),this.children.forEach(s),o=Array.from(this.observer.takeRecords()),r=o.slice();r.length>0;)t.push(r.pop())}}update(t,e={}){t=t||this.observer.takeRecords();const n=new WeakMap;t.map((t=>{const e=this.find(t.target,!0);return null==e?null:n.has(e.domNode)?(n.get(e.domNode).push(t),null):(n.set(e.domNode,[t]),e)})).forEach((t=>{null!=t&&t!==this&&n.has(t.domNode)&&t.update(n.get(t.domNode)||[],e)})),e.mutationsMap=n,n.has(this.domNode)&&super.update(n.get(this.domNode),e),this.optimize(t,e)}};S.blotName="scroll",S.defaultChild=w,S.allowedChildren=[w,k],S.scope=r.BLOCK_BLOT,S.tagName="DIV";const O=S,T=class t extends m{static create(t){return document.createTextNode(t)}static value(t){return t.data}constructor(t,e){super(t,e),this.text=this.statics.value(this.domNode)}deleteAt(t,e){this.domNode.data=this.text=this.text.slice(0,t)+this.text.slice(t+e)}index(t,e){return this.domNode===t?e:-1}insertAt(t,e,n){null==n?(this.text=this.text.slice(0,t)+e+this.text.slice(t),this.domNode.data=this.text):super.insertAt(t,e,n)}length(){return this.text.length}optimize(e){super.optimize(e),this.text=this.statics.value(this.domNode),0===this.text.length?this.remove():this.next instanceof t&&this.next.prev===this&&(this.insertAt(this.length(),this.next.value()),this.next.remove())}position(t,e=!1){return[this.domNode,t]}split(t,e=!1){if(!e){if(0===t)return this;if(t===this.length())return this.next}const n=this.scroll.create(this.domNode.splitText(t));return this.parent.insertBefore(n,this.next||void 0),this.text=this.statics.value(this.domNode),n}update(t,e){t.some((t=>"characterData"===t.type&&t.target===this.domNode))&&(this.text=this.statics.value(this.domNode))}value(){return this.text}};T.blotName="text",T.scope=r.INLINE_BLOT;const j=T}},e={};function n(r){var i=e[r];if(void 0!==i)return i.exports;var s=e[r]={id:r,loaded:!1,exports:{}};return t[r](s,s.exports,n),s.loaded=!0,s.exports}n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,{a:e}),e},n.d=function(t,e){for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.nmd=function(t){return t.paths=[],t.children||(t.children=[]),t};var r={};return function(){"use strict";n.d(r,{default:function(){return It}});var t=n(3729),e=n(8276),i=n(7912),s=n(6003);class o extends s.ClassAttributor{add(t,e){let n=0;if("+1"===e||"-1"===e){const r=this.value(t)||0;n="+1"===e?r+1:r-1}else"number"==typeof e&&(n=e);return 0===n?(this.remove(t),!0):super.add(t,n.toString())}canAdd(t,e){return super.canAdd(t,e)||super.canAdd(t,parseInt(e,10))}value(t){return parseInt(super.value(t),10)||void 0}}var l=new o("indent","ql-indent",{scope:s.Scope.BLOCK,whitelist:[1,2,3,4,5,6,7,8]}),a=n(9698);class c extends a.Ay{static blotName="blockquote";static tagName="blockquote"}var u=c;class h extends a.Ay{static blotName="header";static tagName=["H1","H2","H3","H4","H5","H6"];static formats(t){return this.tagName.indexOf(t.tagName)+1}}var d=h,f=n(580),p=n(6142);class g extends f.A{}g.blotName="list-container",g.tagName="OL";class m extends a.Ay{static create(t){const e=super.create();return e.setAttribute("data-list",t),e}static formats(t){return t.getAttribute("data-list")||void 0}static register(){p.Ay.register(g)}constructor(t,e){super(t,e);const n=e.ownerDocument.createElement("span"),r=n=>{if(!t.isEnabled())return;const r=this.statics.formats(e,t);"checked"===r?(this.format("list","unchecked"),n.preventDefault()):"unchecked"===r&&(this.format("list","checked"),n.preventDefault())};n.addEventListener("mousedown",r),n.addEventListener("touchstart",r),this.attachUI(n)}format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("data-list",e):super.format(t,e)}}m.blotName="list",m.tagName="LI",g.allowedChildren=[m],m.requiredContainer=g;var b=n(9541),y=n(8638),v=n(6772),A=n(664),x=n(4850);class N extends x.A{static blotName="bold";static tagName=["STRONG","B"];static create(){return super.create()}static formats(){return!0}optimize(t){super.optimize(t),this.domNode.tagName!==this.statics.tagName[0]&&this.replaceWith(this.statics.blotName)}}var E=N;class w extends x.A{static blotName="link";static tagName="A";static SANITIZED_URL="about:blank";static PROTOCOL_WHITELIST=["http","https","mailto","tel","sms"];static create(t){const e=super.create(t);return e.setAttribute("href",this.sanitize(t)),e.setAttribute("rel","noopener noreferrer"),e.setAttribute("target","_blank"),e}static formats(t){return t.getAttribute("href")}static sanitize(t){return q(t,this.PROTOCOL_WHITELIST)?t:this.SANITIZED_URL}format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("href",this.constructor.sanitize(e)):super.format(t,e)}}function q(t,e){const n=document.createElement("a");n.href=t;const r=n.href.slice(0,n.href.indexOf(":"));return e.indexOf(r)>-1}class k extends x.A{static blotName="script";static tagName=["SUB","SUP"];static create(t){return"super"===t?document.createElement("sup"):"sub"===t?document.createElement("sub"):super.create(t)}static formats(t){return"SUB"===t.tagName?"sub":"SUP"===t.tagName?"super":void 0}}var _=k;class L extends x.A{static blotName="underline";static tagName="U"}var S=L,O=n(746);class T extends O.A{static blotName="formula";static className="ql-formula";static tagName="SPAN";static create(t){if(null==window.katex)throw new Error("Formula module requires KaTeX.");const e=super.create(t);return"string"==typeof t&&(window.katex.render(t,e,{throwOnError:!1,errorColor:"#f00"}),e.setAttribute("data-value",t)),e}static value(t){return t.getAttribute("data-value")}html(){const{formula:t}=this.value();return`${t}`}}var j=T;const C=["alt","height","width"];class R extends s.EmbedBlot{static blotName="image";static tagName="IMG";static create(t){const e=super.create(t);return"string"==typeof t&&e.setAttribute("src",this.sanitize(t)),e}static formats(t){return C.reduce(((e,n)=>(t.hasAttribute(n)&&(e[n]=t.getAttribute(n)),e)),{})}static match(t){return/\.(jpe?g|gif|png)$/.test(t)||/^data:image\/.+;base64/.test(t)}static sanitize(t){return q(t,["http","https","data"])?t:"//:0"}static value(t){return t.getAttribute("src")}format(t,e){C.indexOf(t)>-1?e?this.domNode.setAttribute(t,e):this.domNode.removeAttribute(t):super.format(t,e)}}var I=R;const B=["height","width"];class M extends a.zo{static blotName="video";static className="ql-video";static tagName="IFRAME";static create(t){const e=super.create(t);return e.setAttribute("frameborder","0"),e.setAttribute("allowfullscreen","true"),e.setAttribute("src",this.sanitize(t)),e}static formats(t){return B.reduce(((e,n)=>(t.hasAttribute(n)&&(e[n]=t.getAttribute(n)),e)),{})}static sanitize(t){return w.sanitize(t)}static value(t){return t.getAttribute("src")}format(t,e){B.indexOf(t)>-1?e?this.domNode.setAttribute(t,e):this.domNode.removeAttribute(t):super.format(t,e)}html(){const{video:t}=this.value();return`${t}`}}var U=M,D=n(9404),P=n(5232),z=n.n(P),F=n(4266),H=n(3036),$=n(4541),V=n(5508),K=n(584);const W=new s.ClassAttributor("code-token","hljs",{scope:s.Scope.INLINE});class Z extends x.A{static formats(t,e){for(;null!=t&&t!==e.domNode;){if(t.classList&&t.classList.contains(D.Ay.className))return super.formats(t,e);t=t.parentNode}}constructor(t,e,n){super(t,e,n),W.add(this.domNode,n)}format(t,e){t!==Z.blotName?super.format(t,e):e?W.add(this.domNode,e):(W.remove(this.domNode),this.domNode.classList.remove(this.statics.className))}optimize(){super.optimize(...arguments),W.value(this.domNode)||this.unwrap()}}Z.blotName="code-token",Z.className="ql-token";class G extends D.Ay{static create(t){const e=super.create(t);return"string"==typeof t&&e.setAttribute("data-language",t),e}static formats(t){return t.getAttribute("data-language")||"plain"}static register(){}format(t,e){t===this.statics.blotName&&e?this.domNode.setAttribute("data-language",e):super.format(t,e)}replaceWith(t,e){return this.formatAt(0,this.length(),Z.blotName,!1),super.replaceWith(t,e)}}class X extends D.EJ{attach(){super.attach(),this.forceNext=!1,this.scroll.emitMount(this)}format(t,e){t===G.blotName&&(this.forceNext=!0,this.children.forEach((n=>{n.format(t,e)})))}formatAt(t,e,n,r){n===G.blotName&&(this.forceNext=!0),super.formatAt(t,e,n,r)}highlight(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(null==this.children.head)return;const n=`${Array.from(this.domNode.childNodes).filter((t=>t!==this.uiNode)).map((t=>t.textContent)).join("\n")}\n`,r=G.formats(this.children.head.domNode);if(e||this.forceNext||this.cachedText!==n){if(n.trim().length>0||null==this.cachedText){const e=this.children.reduce(((t,e)=>t.concat((0,a.mG)(e,!1))),new(z())),i=t(n,r);e.diff(i).reduce(((t,e)=>{let{retain:n,attributes:r}=e;return n?(r&&Object.keys(r).forEach((e=>{[G.blotName,Z.blotName].includes(e)&&this.formatAt(t,n,e,r[e])})),t+n):t}),0)}this.cachedText=n,this.forceNext=!1}}html(t,e){const[n]=this.children.find(t);return`
    \n${(0,V.X)(this.code(t,e))}\n
    `}optimize(t){if(super.optimize(t),null!=this.parent&&null!=this.children.head&&null!=this.uiNode){const t=G.formats(this.children.head.domNode);t!==this.uiNode.value&&(this.uiNode.value=t)}}}X.allowedChildren=[G],G.requiredContainer=X,G.allowedChildren=[Z,$.A,V.A,H.A];class Q extends F.A{static register(){p.Ay.register(Z,!0),p.Ay.register(G,!0),p.Ay.register(X,!0)}constructor(t,e){if(super(t,e),null==this.options.hljs)throw new Error("Syntax module requires highlight.js. Please include the library on the page before Quill.");this.languages=this.options.languages.reduce(((t,e)=>{let{key:n}=e;return t[n]=!0,t}),{}),this.highlightBlot=this.highlightBlot.bind(this),this.initListener(),this.initTimer()}initListener(){this.quill.on(p.Ay.events.SCROLL_BLOT_MOUNT,(t=>{if(!(t instanceof X))return;const e=this.quill.root.ownerDocument.createElement("select");this.options.languages.forEach((t=>{let{key:n,label:r}=t;const i=e.ownerDocument.createElement("option");i.textContent=r,i.setAttribute("value",n),e.appendChild(i)})),e.addEventListener("change",(()=>{t.format(G.blotName,e.value),this.quill.root.focus(),this.highlight(t,!0)})),null==t.uiNode&&(t.attachUI(e),t.children.head&&(e.value=G.formats(t.children.head.domNode)))}))}initTimer(){let t=null;this.quill.on(p.Ay.events.SCROLL_OPTIMIZE,(()=>{t&&clearTimeout(t),t=setTimeout((()=>{this.highlight(),t=null}),this.options.interval)}))}highlight(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(this.quill.selection.composing)return;this.quill.update(p.Ay.sources.USER);const n=this.quill.getSelection();(null==t?this.quill.scroll.descendants(X):[t]).forEach((t=>{t.highlight(this.highlightBlot,e)})),this.quill.update(p.Ay.sources.SILENT),null!=n&&this.quill.setSelection(n,p.Ay.sources.SILENT)}highlightBlot(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"plain";if(e=this.languages[e]?e:"plain","plain"===e)return(0,V.X)(t).split("\n").reduce(((t,n,r)=>(0!==r&&t.insert("\n",{[D.Ay.blotName]:e}),t.insert(n))),new(z()));const n=this.quill.root.ownerDocument.createElement("div");return n.classList.add(D.Ay.className),n.innerHTML=((t,e,n)=>{if("string"==typeof t.versionString){const r=t.versionString.split(".")[0];if(parseInt(r,10)>=11)return t.highlight(n,{language:e}).value}return t.highlight(e,n).value})(this.options.hljs,e,t),(0,K.hV)(this.quill.scroll,n,[(t,e)=>{const n=W.value(t);return n?e.compose((new(z())).retain(e.length(),{[Z.blotName]:n})):e}],[(t,n)=>t.data.split("\n").reduce(((t,n,r)=>(0!==r&&t.insert("\n",{[D.Ay.blotName]:e}),t.insert(n))),n)],new WeakMap)}}Q.DEFAULTS={hljs:window.hljs,interval:1e3,languages:[{key:"plain",label:"Plain"},{key:"r",label:"R"},{key:"bash",label:"Bash"},{key:"cpp",label:"C++"},{key:"cs",label:"C#"},{key:"css",label:"CSS"},{key:"diff",label:"Diff"},{key:"xml",label:"HTML/XML"},{key:"java",label:"Java"},{key:"javascript",label:"JavaScript"},{key:"markdown",label:"Markdown"},{key:"php",label:"PHP"},{key:"python",label:"Python"},{key:"ruby",label:"Ruby"},{key:"sql",label:"SQL"}]};class J extends a.Ay{static blotName="table";static tagName="TD";static create(t){const e=super.create();return t?e.setAttribute("data-row",t):e.setAttribute("data-row",nt()),e}static formats(t){if(t.hasAttribute("data-row"))return t.getAttribute("data-row")}cellOffset(){return this.parent?this.parent.children.indexOf(this):-1}format(t,e){t===J.blotName&&e?this.domNode.setAttribute("data-row",e):super.format(t,e)}row(){return this.parent}rowOffset(){return this.row()?this.row().rowOffset():-1}table(){return this.row()&&this.row().table()}}class Y extends f.A{static blotName="table-row";static tagName="TR";checkMerge(){if(super.checkMerge()&&null!=this.next.children.head){const t=this.children.head.formats(),e=this.children.tail.formats(),n=this.next.children.head.formats(),r=this.next.children.tail.formats();return t.table===e.table&&t.table===n.table&&t.table===r.table}return!1}optimize(t){super.optimize(t),this.children.forEach((t=>{if(null==t.next)return;const e=t.formats(),n=t.next.formats();if(e.table!==n.table){const e=this.splitAfter(t);e&&e.optimize(),this.prev&&this.prev.optimize()}}))}rowOffset(){return this.parent?this.parent.children.indexOf(this):-1}table(){return this.parent&&this.parent.parent}}class tt extends f.A{static blotName="table-body";static tagName="TBODY"}class et extends f.A{static blotName="table-container";static tagName="TABLE";balanceCells(){const t=this.descendants(Y),e=t.reduce(((t,e)=>Math.max(e.children.length,t)),0);t.forEach((t=>{new Array(e-t.children.length).fill(0).forEach((()=>{let e;null!=t.children.head&&(e=J.formats(t.children.head.domNode));const n=this.scroll.create(J.blotName,e);t.appendChild(n),n.optimize()}))}))}cells(t){return this.rows().map((e=>e.children.at(t)))}deleteColumn(t){const[e]=this.descendant(tt);null!=e&&null!=e.children.head&&e.children.forEach((e=>{const n=e.children.at(t);null!=n&&n.remove()}))}insertColumn(t){const[e]=this.descendant(tt);null!=e&&null!=e.children.head&&e.children.forEach((e=>{const n=e.children.at(t),r=J.formats(e.children.head.domNode),i=this.scroll.create(J.blotName,r);e.insertBefore(i,n)}))}insertRow(t){const[e]=this.descendant(tt);if(null==e||null==e.children.head)return;const n=nt(),r=this.scroll.create(Y.blotName);e.children.head.children.forEach((()=>{const t=this.scroll.create(J.blotName,n);r.appendChild(t)}));const i=e.children.at(t);e.insertBefore(r,i)}rows(){const t=this.children.head;return null==t?[]:t.children.map((t=>t))}}function nt(){return`row-${Math.random().toString(36).slice(2,6)}`}et.allowedChildren=[tt],tt.requiredContainer=et,tt.allowedChildren=[Y],Y.requiredContainer=tt,Y.allowedChildren=[J],J.requiredContainer=Y;class rt extends F.A{static register(){p.Ay.register(J),p.Ay.register(Y),p.Ay.register(tt),p.Ay.register(et)}constructor(){super(...arguments),this.listenBalanceCells()}balanceTables(){this.quill.scroll.descendants(et).forEach((t=>{t.balanceCells()}))}deleteColumn(){const[t,,e]=this.getTable();null!=e&&(t.deleteColumn(e.cellOffset()),this.quill.update(p.Ay.sources.USER))}deleteRow(){const[,t]=this.getTable();null!=t&&(t.remove(),this.quill.update(p.Ay.sources.USER))}deleteTable(){const[t]=this.getTable();if(null==t)return;const e=t.offset();t.remove(),this.quill.update(p.Ay.sources.USER),this.quill.setSelection(e,p.Ay.sources.SILENT)}getTable(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.quill.getSelection();if(null==t)return[null,null,null,-1];const[e,n]=this.quill.getLine(t.index);if(null==e||e.statics.blotName!==J.blotName)return[null,null,null,-1];const r=e.parent;return[r.parent.parent,r,e,n]}insertColumn(t){const e=this.quill.getSelection();if(!e)return;const[n,r,i]=this.getTable(e);if(null==i)return;const s=i.cellOffset();n.insertColumn(s+t),this.quill.update(p.Ay.sources.USER);let o=r.rowOffset();0===t&&(o+=1),this.quill.setSelection(e.index+o,e.length,p.Ay.sources.SILENT)}insertColumnLeft(){this.insertColumn(0)}insertColumnRight(){this.insertColumn(1)}insertRow(t){const e=this.quill.getSelection();if(!e)return;const[n,r,i]=this.getTable(e);if(null==i)return;const s=r.rowOffset();n.insertRow(s+t),this.quill.update(p.Ay.sources.USER),t>0?this.quill.setSelection(e,p.Ay.sources.SILENT):this.quill.setSelection(e.index+r.children.length,e.length,p.Ay.sources.SILENT)}insertRowAbove(){this.insertRow(0)}insertRowBelow(){this.insertRow(1)}insertTable(t,e){const n=this.quill.getSelection();if(null==n)return;const r=new Array(t).fill(0).reduce((t=>{const n=new Array(e).fill("\n").join("");return t.insert(n,{table:nt()})}),(new(z())).retain(n.index));this.quill.updateContents(r,p.Ay.sources.USER),this.quill.setSelection(n.index,p.Ay.sources.SILENT),this.balanceTables()}listenBalanceCells(){this.quill.on(p.Ay.events.SCROLL_OPTIMIZE,(t=>{t.some((t=>!!["TD","TR","TBODY","TABLE"].includes(t.target.tagName)&&(this.quill.once(p.Ay.events.TEXT_CHANGE,((t,e,n)=>{n===p.Ay.sources.USER&&this.balanceTables()})),!0)))}))}}var it=rt;const st=(0,n(6078).A)("quill:toolbar");class ot extends F.A{constructor(t,e){if(super(t,e),Array.isArray(this.options.container)){const e=document.createElement("div");e.setAttribute("role","toolbar"),function(t,e){Array.isArray(e[0])||(e=[e]),e.forEach((e=>{const n=document.createElement("span");n.classList.add("ql-formats"),e.forEach((t=>{if("string"==typeof t)lt(n,t);else{const e=Object.keys(t)[0],r=t[e];Array.isArray(r)?function(t,e,n){const r=document.createElement("select");r.classList.add(`ql-${e}`),n.forEach((t=>{const e=document.createElement("option");!1!==t?e.setAttribute("value",String(t)):e.setAttribute("selected","selected"),r.appendChild(e)})),t.appendChild(r)}(n,e,r):lt(n,e,r)}})),t.appendChild(n)}))}(e,this.options.container),t.container?.parentNode?.insertBefore(e,t.container),this.container=e}else"string"==typeof this.options.container?this.container=document.querySelector(this.options.container):this.container=this.options.container;this.container instanceof HTMLElement?(this.container.classList.add("ql-toolbar"),this.controls=[],this.handlers={},this.options.handlers&&Object.keys(this.options.handlers).forEach((t=>{const e=this.options.handlers?.[t];e&&this.addHandler(t,e)})),Array.from(this.container.querySelectorAll("button, select")).forEach((t=>{this.attach(t)})),this.quill.on(p.Ay.events.EDITOR_CHANGE,(()=>{const[t]=this.quill.selection.getRange();this.update(t)}))):st.error("Container required for toolbar",this.options)}addHandler(t,e){this.handlers[t]=e}attach(t){let e=Array.from(t.classList).find((t=>0===t.indexOf("ql-")));if(!e)return;if(e=e.slice(3),"BUTTON"===t.tagName&&t.setAttribute("type","button"),null==this.handlers[e]&&null==this.quill.scroll.query(e))return void st.warn("ignoring attaching to nonexistent format",e,t);const n="SELECT"===t.tagName?"change":"click";t.addEventListener(n,(n=>{let r;if("SELECT"===t.tagName){if(t.selectedIndex<0)return;const e=t.options[t.selectedIndex];r=!e.hasAttribute("selected")&&(e.value||!1)}else r=!t.classList.contains("ql-active")&&(t.value||!t.hasAttribute("value")),n.preventDefault();this.quill.focus();const[i]=this.quill.selection.getRange();if(null!=this.handlers[e])this.handlers[e].call(this,r);else if(this.quill.scroll.query(e).prototype instanceof s.EmbedBlot){if(r=prompt(`Enter ${e}`),!r)return;this.quill.updateContents((new(z())).retain(i.index).delete(i.length).insert({[e]:r}),p.Ay.sources.USER)}else this.quill.format(e,r,p.Ay.sources.USER);this.update(i)})),this.controls.push([e,t])}update(t){const e=null==t?{}:this.quill.getFormat(t);this.controls.forEach((n=>{const[r,i]=n;if("SELECT"===i.tagName){let n=null;if(null==t)n=null;else if(null==e[r])n=i.querySelector("option[selected]");else if(!Array.isArray(e[r])){let t=e[r];"string"==typeof t&&(t=t.replace(/"/g,'\\"')),n=i.querySelector(`option[value="${t}"]`)}null==n?(i.value="",i.selectedIndex=-1):n.selected=!0}else if(null==t)i.classList.remove("ql-active"),i.setAttribute("aria-pressed","false");else if(i.hasAttribute("value")){const t=e[r],n=t===i.getAttribute("value")||null!=t&&t.toString()===i.getAttribute("value")||null==t&&!i.getAttribute("value");i.classList.toggle("ql-active",n),i.setAttribute("aria-pressed",n.toString())}else{const t=null!=e[r];i.classList.toggle("ql-active",t),i.setAttribute("aria-pressed",t.toString())}}))}}function lt(t,e,n){const r=document.createElement("button");r.setAttribute("type","button"),r.classList.add(`ql-${e}`),r.setAttribute("aria-pressed","false"),null!=n?(r.value=n,r.setAttribute("aria-label",`${e}: ${n}`)):r.setAttribute("aria-label",e),t.appendChild(r)}ot.DEFAULTS={},ot.DEFAULTS={container:null,handlers:{clean(){const t=this.quill.getSelection();if(null!=t)if(0===t.length){const t=this.quill.getFormat();Object.keys(t).forEach((t=>{null!=this.quill.scroll.query(t,s.Scope.INLINE)&&this.quill.format(t,!1,p.Ay.sources.USER)}))}else this.quill.removeFormat(t.index,t.length,p.Ay.sources.USER)},direction(t){const{align:e}=this.quill.getFormat();"rtl"===t&&null==e?this.quill.format("align","right",p.Ay.sources.USER):t||"right"!==e||this.quill.format("align",!1,p.Ay.sources.USER),this.quill.format("direction",t,p.Ay.sources.USER)},indent(t){const e=this.quill.getSelection(),n=this.quill.getFormat(e),r=parseInt(n.indent||0,10);if("+1"===t||"-1"===t){let e="+1"===t?1:-1;"rtl"===n.direction&&(e*=-1),this.quill.format("indent",r+e,p.Ay.sources.USER)}},link(t){!0===t&&(t=prompt("Enter link URL:")),this.quill.format("link",t,p.Ay.sources.USER)},list(t){const e=this.quill.getSelection(),n=this.quill.getFormat(e);"check"===t?"checked"===n.list||"unchecked"===n.list?this.quill.format("list",!1,p.Ay.sources.USER):this.quill.format("list","unchecked",p.Ay.sources.USER):this.quill.format("list",t,p.Ay.sources.USER)}}};const at='';var ct={align:{"":'',center:'',right:'',justify:''},background:'',blockquote:'',bold:'',clean:'',code:at,"code-block":at,color:'',direction:{"":'',rtl:''},formula:'',header:{1:'',2:'',3:'',4:'',5:'',6:''},italic:'',image:'',indent:{"+1":'',"-1":''},link:'',list:{bullet:'',check:'',ordered:''},script:{sub:'',super:''},strike:'',table:'',underline:'',video:''};let ut=0;function ht(t,e){t.setAttribute(e,`${!("true"===t.getAttribute(e))}`)}var dt=class{constructor(t){this.select=t,this.container=document.createElement("span"),this.buildPicker(),this.select.style.display="none",this.select.parentNode.insertBefore(this.container,this.select),this.label.addEventListener("mousedown",(()=>{this.togglePicker()})),this.label.addEventListener("keydown",(t=>{switch(t.key){case"Enter":this.togglePicker();break;case"Escape":this.escape(),t.preventDefault()}})),this.select.addEventListener("change",this.update.bind(this))}togglePicker(){this.container.classList.toggle("ql-expanded"),ht(this.label,"aria-expanded"),ht(this.options,"aria-hidden")}buildItem(t){const e=document.createElement("span");e.tabIndex="0",e.setAttribute("role","button"),e.classList.add("ql-picker-item");const n=t.getAttribute("value");return n&&e.setAttribute("data-value",n),t.textContent&&e.setAttribute("data-label",t.textContent),e.addEventListener("click",(()=>{this.selectItem(e,!0)})),e.addEventListener("keydown",(t=>{switch(t.key){case"Enter":this.selectItem(e,!0),t.preventDefault();break;case"Escape":this.escape(),t.preventDefault()}})),e}buildLabel(){const t=document.createElement("span");return t.classList.add("ql-picker-label"),t.innerHTML='',t.tabIndex="0",t.setAttribute("role","button"),t.setAttribute("aria-expanded","false"),this.container.appendChild(t),t}buildOptions(){const t=document.createElement("span");t.classList.add("ql-picker-options"),t.setAttribute("aria-hidden","true"),t.tabIndex="-1",t.id=`ql-picker-options-${ut}`,ut+=1,this.label.setAttribute("aria-controls",t.id),this.options=t,Array.from(this.select.options).forEach((e=>{const n=this.buildItem(e);t.appendChild(n),!0===e.selected&&this.selectItem(n)})),this.container.appendChild(t)}buildPicker(){Array.from(this.select.attributes).forEach((t=>{this.container.setAttribute(t.name,t.value)})),this.container.classList.add("ql-picker"),this.label=this.buildLabel(),this.buildOptions()}escape(){this.close(),setTimeout((()=>this.label.focus()),1)}close(){this.container.classList.remove("ql-expanded"),this.label.setAttribute("aria-expanded","false"),this.options.setAttribute("aria-hidden","true")}selectItem(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const n=this.container.querySelector(".ql-selected");t!==n&&(null!=n&&n.classList.remove("ql-selected"),null!=t&&(t.classList.add("ql-selected"),this.select.selectedIndex=Array.from(t.parentNode.children).indexOf(t),t.hasAttribute("data-value")?this.label.setAttribute("data-value",t.getAttribute("data-value")):this.label.removeAttribute("data-value"),t.hasAttribute("data-label")?this.label.setAttribute("data-label",t.getAttribute("data-label")):this.label.removeAttribute("data-label"),e&&(this.select.dispatchEvent(new Event("change")),this.close())))}update(){let t;if(this.select.selectedIndex>-1){const e=this.container.querySelector(".ql-picker-options").children[this.select.selectedIndex];t=this.select.options[this.select.selectedIndex],this.selectItem(e)}else this.selectItem(null);const e=null!=t&&t!==this.select.querySelector("option[selected]");this.label.classList.toggle("ql-active",e)}},ft=class extends dt{constructor(t,e){super(t),this.label.innerHTML=e,this.container.classList.add("ql-color-picker"),Array.from(this.container.querySelectorAll(".ql-picker-item")).slice(0,7).forEach((t=>{t.classList.add("ql-primary")}))}buildItem(t){const e=super.buildItem(t);return e.style.backgroundColor=t.getAttribute("value")||"",e}selectItem(t,e){super.selectItem(t,e);const n=this.label.querySelector(".ql-color-label"),r=t&&t.getAttribute("data-value")||"";n&&("line"===n.tagName?n.style.stroke=r:n.style.fill=r)}},pt=class extends dt{constructor(t,e){super(t),this.container.classList.add("ql-icon-picker"),Array.from(this.container.querySelectorAll(".ql-picker-item")).forEach((t=>{t.innerHTML=e[t.getAttribute("data-value")||""]})),this.defaultItem=this.container.querySelector(".ql-selected"),this.selectItem(this.defaultItem)}selectItem(t,e){super.selectItem(t,e);const n=t||this.defaultItem;if(null!=n){if(this.label.innerHTML===n.innerHTML)return;this.label.innerHTML=n.innerHTML}}},gt=class{constructor(t,e){this.quill=t,this.boundsContainer=e||document.body,this.root=t.addContainer("ql-tooltip"),this.root.innerHTML=this.constructor.TEMPLATE,(t=>{const{overflowY:e}=getComputedStyle(t,null);return"visible"!==e&&"clip"!==e})(this.quill.root)&&this.quill.root.addEventListener("scroll",(()=>{this.root.style.marginTop=-1*this.quill.root.scrollTop+"px"})),this.hide()}hide(){this.root.classList.add("ql-hidden")}position(t){const e=t.left+t.width/2-this.root.offsetWidth/2,n=t.bottom+this.quill.root.scrollTop;this.root.style.left=`${e}px`,this.root.style.top=`${n}px`,this.root.classList.remove("ql-flip");const r=this.boundsContainer.getBoundingClientRect(),i=this.root.getBoundingClientRect();let s=0;if(i.right>r.right&&(s=r.right-i.right,this.root.style.left=`${e+s}px`),i.leftr.bottom){const e=i.bottom-i.top,r=t.bottom-t.top+e;this.root.style.top=n-r+"px",this.root.classList.add("ql-flip")}return s}show(){this.root.classList.remove("ql-editing"),this.root.classList.remove("ql-hidden")}},mt=n(8347),bt=n(5374),yt=n(9609);const vt=[!1,"center","right","justify"],At=["#000000","#e60000","#ff9900","#ffff00","#008a00","#0066cc","#9933ff","#ffffff","#facccc","#ffebcc","#ffffcc","#cce8cc","#cce0f5","#ebd6ff","#bbbbbb","#f06666","#ffc266","#ffff66","#66b966","#66a3e0","#c285ff","#888888","#a10000","#b26b00","#b2b200","#006100","#0047b2","#6b24b2","#444444","#5c0000","#663d00","#666600","#003700","#002966","#3d1466"],xt=[!1,"serif","monospace"],Nt=["1","2","3",!1],Et=["small",!1,"large","huge"];class wt extends yt.A{constructor(t,e){super(t,e);const n=e=>{document.body.contains(t.root)?(null==this.tooltip||this.tooltip.root.contains(e.target)||document.activeElement===this.tooltip.textbox||this.quill.hasFocus()||this.tooltip.hide(),null!=this.pickers&&this.pickers.forEach((t=>{t.container.contains(e.target)||t.close()}))):document.body.removeEventListener("click",n)};t.emitter.listenDOM("click",document.body,n)}addModule(t){const e=super.addModule(t);return"toolbar"===t&&this.extendToolbar(e),e}buildButtons(t,e){Array.from(t).forEach((t=>{(t.getAttribute("class")||"").split(/\s+/).forEach((n=>{if(n.startsWith("ql-")&&(n=n.slice(3),null!=e[n]))if("direction"===n)t.innerHTML=e[n][""]+e[n].rtl;else if("string"==typeof e[n])t.innerHTML=e[n];else{const r=t.value||"";null!=r&&e[n][r]&&(t.innerHTML=e[n][r])}}))}))}buildPickers(t,e){this.pickers=Array.from(t).map((t=>{if(t.classList.contains("ql-align")&&(null==t.querySelector("option")&&kt(t,vt),"object"==typeof e.align))return new pt(t,e.align);if(t.classList.contains("ql-background")||t.classList.contains("ql-color")){const n=t.classList.contains("ql-background")?"background":"color";return null==t.querySelector("option")&&kt(t,At,"background"===n?"#ffffff":"#000000"),new ft(t,e[n])}return null==t.querySelector("option")&&(t.classList.contains("ql-font")?kt(t,xt):t.classList.contains("ql-header")?kt(t,Nt):t.classList.contains("ql-size")&&kt(t,Et)),new dt(t)})),this.quill.on(bt.A.events.EDITOR_CHANGE,(()=>{this.pickers.forEach((t=>{t.update()}))}))}}wt.DEFAULTS=(0,mt.A)({},yt.A.DEFAULTS,{modules:{toolbar:{handlers:{formula(){this.quill.theme.tooltip.edit("formula")},image(){let t=this.container.querySelector("input.ql-image[type=file]");null==t&&(t=document.createElement("input"),t.setAttribute("type","file"),t.setAttribute("accept",this.quill.uploader.options.mimetypes.join(", ")),t.classList.add("ql-image"),t.addEventListener("change",(()=>{const e=this.quill.getSelection(!0);this.quill.uploader.upload(e,t.files),t.value=""})),this.container.appendChild(t)),t.click()},video(){this.quill.theme.tooltip.edit("video")}}}}});class qt extends gt{constructor(t,e){super(t,e),this.textbox=this.root.querySelector('input[type="text"]'),this.listen()}listen(){this.textbox.addEventListener("keydown",(t=>{"Enter"===t.key?(this.save(),t.preventDefault()):"Escape"===t.key&&(this.cancel(),t.preventDefault())}))}cancel(){this.hide(),this.restoreFocus()}edit(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"link",e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(this.root.classList.remove("ql-hidden"),this.root.classList.add("ql-editing"),null==this.textbox)return;null!=e?this.textbox.value=e:t!==this.root.getAttribute("data-mode")&&(this.textbox.value="");const n=this.quill.getBounds(this.quill.selection.savedRange);null!=n&&this.position(n),this.textbox.select(),this.textbox.setAttribute("placeholder",this.textbox.getAttribute(`data-${t}`)||""),this.root.setAttribute("data-mode",t)}restoreFocus(){this.quill.focus({preventScroll:!0})}save(){let{value:t}=this.textbox;switch(this.root.getAttribute("data-mode")){case"link":{const{scrollTop:e}=this.quill.root;this.linkRange?(this.quill.formatText(this.linkRange,"link",t,bt.A.sources.USER),delete this.linkRange):(this.restoreFocus(),this.quill.format("link",t,bt.A.sources.USER)),this.quill.root.scrollTop=e;break}case"video":t=function(t){let e=t.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtube\.com\/watch.*v=([a-zA-Z0-9_-]+)/)||t.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtu\.be\/([a-zA-Z0-9_-]+)/);return e?`${e[1]||"https"}://www.youtube.com/embed/${e[2]}?showinfo=0`:(e=t.match(/^(?:(https?):\/\/)?(?:www\.)?vimeo\.com\/(\d+)/))?`${e[1]||"https"}://player.vimeo.com/video/${e[2]}/`:t}(t);case"formula":{if(!t)break;const e=this.quill.getSelection(!0);if(null!=e){const n=e.index+e.length;this.quill.insertEmbed(n,this.root.getAttribute("data-mode"),t,bt.A.sources.USER),"formula"===this.root.getAttribute("data-mode")&&this.quill.insertText(n+1," ",bt.A.sources.USER),this.quill.setSelection(n+2,bt.A.sources.USER)}break}}this.textbox.value="",this.hide()}}function kt(t,e){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];e.forEach((e=>{const r=document.createElement("option");e===n?r.setAttribute("selected","selected"):r.setAttribute("value",String(e)),t.appendChild(r)}))}var _t=n(8298);const Lt=[["bold","italic","link"],[{header:1},{header:2},"blockquote"]];class St extends qt{static TEMPLATE=['','
    ','','',"
    "].join("");constructor(t,e){super(t,e),this.quill.on(bt.A.events.EDITOR_CHANGE,((t,e,n,r)=>{if(t===bt.A.events.SELECTION_CHANGE)if(null!=e&&e.length>0&&r===bt.A.sources.USER){this.show(),this.root.style.left="0px",this.root.style.width="",this.root.style.width=`${this.root.offsetWidth}px`;const t=this.quill.getLines(e.index,e.length);if(1===t.length){const t=this.quill.getBounds(e);null!=t&&this.position(t)}else{const n=t[t.length-1],r=this.quill.getIndex(n),i=Math.min(n.length()-1,e.index+e.length-r),s=this.quill.getBounds(new _t.Q(r,i));null!=s&&this.position(s)}}else document.activeElement!==this.textbox&&this.quill.hasFocus()&&this.hide()}))}listen(){super.listen(),this.root.querySelector(".ql-close").addEventListener("click",(()=>{this.root.classList.remove("ql-editing")})),this.quill.on(bt.A.events.SCROLL_OPTIMIZE,(()=>{setTimeout((()=>{if(this.root.classList.contains("ql-hidden"))return;const t=this.quill.getSelection();if(null!=t){const e=this.quill.getBounds(t);null!=e&&this.position(e)}}),1)}))}cancel(){this.show()}position(t){const e=super.position(t),n=this.root.querySelector(".ql-tooltip-arrow");return n.style.marginLeft="",0!==e&&(n.style.marginLeft=-1*e-n.offsetWidth/2+"px"),e}}class Ot extends wt{constructor(t,e){null!=e.modules.toolbar&&null==e.modules.toolbar.container&&(e.modules.toolbar.container=Lt),super(t,e),this.quill.container.classList.add("ql-bubble")}extendToolbar(t){this.tooltip=new St(this.quill,this.options.bounds),null!=t.container&&(this.tooltip.root.appendChild(t.container),this.buildButtons(t.container.querySelectorAll("button"),ct),this.buildPickers(t.container.querySelectorAll("select"),ct))}}Ot.DEFAULTS=(0,mt.A)({},wt.DEFAULTS,{modules:{toolbar:{handlers:{link(t){t?this.quill.theme.tooltip.edit():this.quill.format("link",!1,p.Ay.sources.USER)}}}}});const Tt=[[{header:["1","2","3",!1]}],["bold","italic","underline","link"],[{list:"ordered"},{list:"bullet"}],["clean"]];class jt extends qt{static TEMPLATE=['','','',''].join("");preview=this.root.querySelector("a.ql-preview");listen(){super.listen(),this.root.querySelector("a.ql-action").addEventListener("click",(t=>{this.root.classList.contains("ql-editing")?this.save():this.edit("link",this.preview.textContent),t.preventDefault()})),this.root.querySelector("a.ql-remove").addEventListener("click",(t=>{if(null!=this.linkRange){const t=this.linkRange;this.restoreFocus(),this.quill.formatText(t,"link",!1,bt.A.sources.USER),delete this.linkRange}t.preventDefault(),this.hide()})),this.quill.on(bt.A.events.SELECTION_CHANGE,((t,e,n)=>{if(null!=t){if(0===t.length&&n===bt.A.sources.USER){const[e,n]=this.quill.scroll.descendant(w,t.index);if(null!=e){this.linkRange=new _t.Q(t.index-n,e.length());const r=w.formats(e.domNode);this.preview.textContent=r,this.preview.setAttribute("href",r),this.show();const i=this.quill.getBounds(this.linkRange);return void(null!=i&&this.position(i))}}else delete this.linkRange;this.hide()}}))}show(){super.show(),this.root.removeAttribute("data-mode")}}class Ct extends wt{constructor(t,e){null!=e.modules.toolbar&&null==e.modules.toolbar.container&&(e.modules.toolbar.container=Tt),super(t,e),this.quill.container.classList.add("ql-snow")}extendToolbar(t){null!=t.container&&(t.container.classList.add("ql-snow"),this.buildButtons(t.container.querySelectorAll("button"),ct),this.buildPickers(t.container.querySelectorAll("select"),ct),this.tooltip=new jt(this.quill,this.options.bounds),t.container.querySelector(".ql-link")&&this.quill.keyboard.addBinding({key:"k",shortKey:!0},((e,n)=>{t.handlers.link.call(t,!n.format.link)})))}}Ct.DEFAULTS=(0,mt.A)({},wt.DEFAULTS,{modules:{toolbar:{handlers:{link(t){if(t){const t=this.quill.getSelection();if(null==t||0===t.length)return;let e=this.quill.getText(t);/^\S+@\S+\.\S+$/.test(e)&&0!==e.indexOf("mailto:")&&(e=`mailto:${e}`);const{tooltip:n}=this.quill.theme;n.edit("link",e)}else this.quill.format("link",!1,p.Ay.sources.USER)}}}}});var Rt=Ct;t.default.register({"attributors/attribute/direction":i.Mc,"attributors/class/align":e.qh,"attributors/class/background":b.l,"attributors/class/color":y.g3,"attributors/class/direction":i.sY,"attributors/class/font":v.q,"attributors/class/size":A.U,"attributors/style/align":e.Hu,"attributors/style/background":b.s,"attributors/style/color":y.JM,"attributors/style/direction":i.VL,"attributors/style/font":v.z,"attributors/style/size":A.r},!0),t.default.register({"formats/align":e.qh,"formats/direction":i.sY,"formats/indent":l,"formats/background":b.s,"formats/color":y.JM,"formats/font":v.q,"formats/size":A.U,"formats/blockquote":u,"formats/code-block":D.Ay,"formats/header":d,"formats/list":m,"formats/bold":E,"formats/code":D.Cy,"formats/italic":class extends E{static blotName="italic";static tagName=["EM","I"]},"formats/link":w,"formats/script":_,"formats/strike":class extends E{static blotName="strike";static tagName=["S","STRIKE"]},"formats/underline":S,"formats/formula":j,"formats/image":I,"formats/video":U,"modules/syntax":Q,"modules/table":it,"modules/toolbar":ot,"themes/bubble":Ot,"themes/snow":Rt,"ui/icons":ct,"ui/picker":dt,"ui/icon-picker":pt,"ui/color-picker":ft,"ui/tooltip":gt},!0);var It=t.default}(),r.default}()})); diff --git a/Desktop/html/js/utils.js b/Desktop/html/js/utils.js index 5669de5b02..2ce66105b5 100644 --- a/Desktop/html/js/utils.js +++ b/Desktop/html/js/utils.js @@ -1,4 +1,4 @@ -function formatColumn(column, type, format, alignNumbers, combine, modelFootnotes, html = true) { +function formatColumn(column, type, format, alignNumbers, combine, modelFootnotes, html = true, errorOnMixed = false) { /** * Prepares the columns of a table to the required format * @param column @@ -8,15 +8,33 @@ function formatColumn(column, type, format, alignNumbers, combine, modelFootnote * @param combine * @param modelFootnotes * @param html html render or latex code. Default is true + * @param errorOnMixed internal, used to avoid infinite loops */ let columnCells = Array(column.length); - if (type === "string" || typeof format == "undefined") { + if (type === "mixed") { + + if (errorOnMixed) { + // or throw an error? But how? + return "Error: nested mixed columns are not supported!"; + } + + // call formatColumn for each row of the mixed column + for (let rowNo = 0; rowNo < column.length; rowNo++) { + // we need to construct the array [column[rowNo].content.value] because column.length otherwise does not exist. + columnCells[rowNo] = formatColumn([{content: column[rowNo].content.value}], column[rowNo].content.type, column[rowNo].content.format, alignNumbers, combine, modelFootnotes, html, true)[0]; + } + + return columnCells; + + } + + if (type === "string" || typeof format == "undefined" || format === null) { for (let rowNo = 0; rowNo < column.length; rowNo++) { - let clazz = (type == "string") ? "text" : "number"; + let clazz = (type === "string" && !errorOnMixed) ? "text" : "number"; let cell = column[rowNo]; let content = cell.content; let formatted; @@ -99,6 +117,18 @@ function formatColumn(column, type, format, alignNumbers, combine, modelFootnote log10 = true; } + for (var rowNo = 0; rowNo < column.length; rowNo++) { + var cell = column[rowNo] + var content = cell.content + + if (typeof(content) !== "number" || typeof(content) !== "Number") { + if (isNaN(parseFloat(content))) // isn't a number + continue + console.warn("You are delivering a result that should be a number as a string, We will do our best :("); + cell.content = content = parseFloat(content) + } + } + if (isFinite(sf)) { var upperLimit = 1e6 @@ -441,7 +471,7 @@ function formatColumn(column, type, format, alignNumbers, combine, modelFootnote } else { - for (var rowNo = 0; rowNo < column.length; rowNo++) { + for (let rowNo = 0; rowNo < column.length; rowNo++) { var cell = column[rowNo] var content = cell.content diff --git a/Desktop/main.cpp b/Desktop/main.cpp index 57cf7eec7b..6ab2a84578 100644 --- a/Desktop/main.cpp +++ b/Desktop/main.cpp @@ -52,7 +52,7 @@ const std::string jaspExtension = ".jasp", bool runJaspEngineJunctionFixer(int argc, char *argv[], bool removeJunctions = false, bool exitAfterwards = true) { QApplication * app = exitAfterwards ? new QApplication(argc, argv) : nullptr; - QProcessEnvironment env = ProcessHelper::getProcessEnvironmentForJaspEngine(); + QProcessEnvironment env = ProcessHelper::getProcessEnvironmentForJaspEngine(true); QString workDir = QFileInfo( QCoreApplication::applicationFilePath() ).absoluteDir().absolutePath(); QProcess engine; @@ -64,7 +64,8 @@ bool runJaspEngineJunctionFixer(int argc, char *argv[], bool removeJunctions = f //remove any leftover ModuleDir QDir modulesDir(AppDirs::bundledModulesDir()); - if(modulesDir.exists() && AppDirs::bundledModulesDir().contains("Modules", Qt::CaseInsensitive) && DynamicRuntimeInfo::getInstance()->getRuntimeEnvironment() != DynamicRuntimeInfo::ZIP) { + if(modulesDir.exists() && AppDirs::bundledModulesDir().contains("Modules", Qt::CaseInsensitive) && DynamicRuntimeInfo::getInstance()->getRuntimeEnvironment() != DynamicRuntimeInfo::ZIP) + { std::function removeDir = [&](QDir x) -> void { for(const auto& entry : x.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files)) { @@ -120,7 +121,7 @@ bool runJaspEngineJunctionFixer(int argc, char *argv[], bool removeJunctions = f #endif -void parseArguments(int argc, char *argv[], std::string & filePath, bool & unitTest, bool & dirTest, int & timeOut, bool & save, bool & logToFile, bool & hideJASP, bool & safeGraphics, Json::Value & dbJson, QString & reportingDir) +void parseArguments(int argc, char *argv[], std::string & filePath, bool & newData, bool & unitTest, bool & dirTest, int & timeOut, bool & save, bool & logToFile, bool & hideJASP, bool & safeGraphics, Json::Value & dbJson, QString & reportingDir) { filePath = ""; unitTest = false; @@ -129,6 +130,7 @@ void parseArguments(int argc, char *argv[], std::string & filePath, bool & unitT logToFile = false; hideJASP = false; safeGraphics = false; + newData = false; reportingDir = ""; timeOut = 10; dbJson = Json::nullValue; @@ -144,6 +146,7 @@ void parseArguments(int argc, char *argv[], std::string & filePath, bool & unitT else if(args[arg] == "--logToFile") logToFile = true; else if(args[arg] == "--hide") hideJASP = true; else if(args[arg] == "--safeGraphics") safeGraphics = true; + else if(args[arg] == "--newData") newData = true; #ifdef _WIN32 else if(args[arg] == junctionArg) runJaspEngineJunctionFixer(argc, argv, false); //Run the junctionfixer, it will exit the application btw! else if(args[arg] == removeJunctionsArg) runJaspEngineJunctionFixer(argc, argv, true); //Remove the junctions @@ -407,7 +410,8 @@ int main(int argc, char *argv[]) save, logToFile, hideJASP, - safeGraphics; + safeGraphics, + newData; int timeOut; Json::Value dbJson; @@ -415,7 +419,7 @@ int main(int argc, char *argv[]) QCoreApplication::setOrganizationDomain("jasp-stats.org"); QCoreApplication::setApplicationName("JASP"); - parseArguments(argc, argv, filePath, unitTest, dirTest, timeOut, save, logToFile, hideJASP, safeGraphics, dbJson, reportingDir); + parseArguments(argc, argv, filePath, newData, unitTest, dirTest, timeOut, save, logToFile, hideJASP, safeGraphics, dbJson, reportingDir); if(safeGraphics) Settings::setValue(Settings::SAFE_GRAPHICS_MODE, true); else safeGraphics = Settings::value(Settings::SAFE_GRAPHICS_MODE).toBool(); @@ -447,12 +451,6 @@ int main(int argc, char *argv[]) args.push_back("minimal"); } - if(hideJASP) - { - args.push_back("-platform"); - args.push_back("minimal"); - } - PlotSchemeHandler::createUrlScheme(); //Needs to be done *before* creating PlotSchemeHandler instance and also before QApplication is instantiated ImgSchemeHandler::createUrlScheme(); @@ -525,7 +523,7 @@ int main(int argc, char *argv[]) msgBox->hide(); } #endif - a.init(filePathQ, unitTest, timeOut, save, logToFile, dbJson, reportingDir); + a.init(filePathQ, newData, unitTest, timeOut, save, logToFile, dbJson, reportingDir); try { diff --git a/Desktop/mainwindow.cpp b/Desktop/mainwindow.cpp index 88c4c07f14..f0612cf20f 100644 --- a/Desktop/mainwindow.cpp +++ b/Desktop/mainwindow.cpp @@ -32,12 +32,11 @@ #include #include "log.h" -#include "dirs.h" #include "timers.h" #include "appinfo.h" #include "tempfiles.h" #include "processinfo.h" -#include "columnutils.h" + #include "mainwindow.h" #include "analysisform.h" @@ -46,6 +45,7 @@ #include "controls/comboboxbase.h" #include "controls/textinputbase.h" #include "controls/componentslistbase.h" +#include "controls/rsyntaxhighlighter.h" #include "controls/factorsformbase.h" #include "controls/inputlistbase.h" #include "controls/textareabase.h" @@ -180,6 +180,7 @@ MainWindow::MainWindow(QApplication * application) : QObject(application), _appl qmlRegisterType ("JASP", 1, 0, "ComboBoxBase" ); qmlRegisterType ("JASP", 1, 0, "RadioButtonBase" ); qmlRegisterType ("JASP", 1, 0, "RadioButtonsGroupBase" ); + qmlRegisterType ("JASP", 1, 0, "RSyntaxHighlighterQuick" ); qmlRegisterType ("JASP", 1, 0, "ComponentsListBase" ); qmlRegisterType ("JASP", 1, 0, "FactorsFormBase" ); qmlRegisterType ("JASP", 1, 0, "InputListBase" ); @@ -552,7 +553,6 @@ void MainWindow::makeConnections() connect(_ribbonModel, &RibbonModel::analysisClickedSignal, _analyses, &Analyses::analysisClickedHandler ); connect(_ribbonModel, &RibbonModel::showRCommander, this, &MainWindow::showRCommander ); - connect(_ribbonModel, &RibbonModel::generateEmptyData, _package, &DataSetPackage::generateEmptyData ); connect(_ribbonModel, &RibbonModel::dataModeChanged, _package, &DataSetPackage::dataModeChanged ); connect(_ribbonModel, &RibbonModel::setDataSynchronisation, _package, &DataSetPackage::setSynchingExternallyFriendly ); @@ -727,7 +727,7 @@ void MainWindow::loadQML() connect(_ribbonModel, &RibbonModel::dataUndo, DataSetView::mainDataViewer(), &DataSetView::undo); connect(_ribbonModel, &RibbonModel::dataRedo, DataSetView::mainDataViewer(), &DataSetView::redo); connect(this, &MainWindow::resizeData, DataSetView::mainDataViewer(), &DataSetView::resizeData); - + connect(_ribbonModel, &RibbonModel::showNewData, this, &MainWindow::showNewData); //connect(DataSetView::lastInstancedDataSetView(), &DataSetView::selectionStartChanged, _columnModel, &ColumnModel::changeSelectedColumn); @@ -902,6 +902,11 @@ void MainWindow::open(QString filepath) else _openOnLoadFilename = filepath; } +void MainWindow::showNewData() +{ + _package->generateEmptyData(); + _ribbonModel->showData(); +} void MainWindow::open(const Json::Value & dbJson) { @@ -1175,7 +1180,14 @@ void MainWindow::connectFileEventCompleted(FileEvent * event) void MainWindow::dataSetIORequestHandler(FileEvent *event) { - if (event->operation() == FileEvent::FileOpen) + if (event->operation() == FileEvent::FileNew) + { + if (_package->isLoaded()) + QProcess::startDetached(QCoreApplication::applicationFilePath(), QStringList("--newData")); + else + showNewData(); + } + else if (event->operation() == FileEvent::FileOpen) { if (_package->isLoaded()) { @@ -1301,7 +1313,10 @@ void MainWindow::dataSetIOCompleted(FileEvent *event) { hideProgress(); - if (event->operation() == FileEvent::FileOpen) + if (event->operation() == FileEvent::FileNew) + { + } + else if (event->operation() == FileEvent::FileOpen) { if (event->isSuccessful()) { @@ -1467,6 +1482,7 @@ void MainWindow::qmlLoaded() { Log::log() << "MainWindow::qmlLoaded()" << std::endl; _qmlLoaded = true; + emit qmlLoadedChanged(); handleDeferredFileLoad(); } @@ -1721,7 +1737,7 @@ bool MainWindow::startDataEditorHandler() else { QString caption = "Find Data File"; - QString filter = "Data File (*.csv *.txt *.tsv *.sav *.ods)"; + QString filter = "Data File (*.csv *.txt *.tsv *.sav *.ods *.xls *.xlsx)"; dataFilePath = MessageForwarder::browseOpenFile(caption, "", filter); if (dataFilePath == "") diff --git a/Desktop/mainwindow.h b/Desktop/mainwindow.h index 87cc37c94a..3f3deb1bca 100644 --- a/Desktop/mainwindow.h +++ b/Desktop/mainwindow.h @@ -102,6 +102,7 @@ class MainWindow : public QObject static MainWindow * singleton() { return _singleton; } + void showNewData(); void open(QString filepath); void open(const Json::Value & dbJson); void testLoadedJaspFile(int timeOut, bool save); @@ -249,6 +250,7 @@ public slots: void communityVisibleChanged(); void contactTextChanged(); void resizeData(int row, int col); + void qmlLoadedChanged(); private slots: void resultsPageLoaded(); diff --git a/Desktop/modules/analysisentry.cpp b/Desktop/modules/analysisentry.cpp index 95d5598aff..fdfcbbe6e2 100644 --- a/Desktop/modules/analysisentry.cpp +++ b/Desktop/modules/analysisentry.cpp @@ -23,8 +23,8 @@ namespace Modules { -AnalysisEntry::AnalysisEntry(std::function specialFunc, std::string internalTitle, std::string menuTitle, bool requiresData, std::string icon) - : _title(internalTitle), _function(internalTitle), _menu(menuTitle), _isSeparator(false), _isGroupTitle(!specialFunc), _requiresData(requiresData), _icon(icon), _specialFunc(specialFunc) +AnalysisEntry::AnalysisEntry(std::function specialFunc, std::string internalTitle, std::function menuTitleF, bool requiresData, std::string icon) + : _title(internalTitle), _function(internalTitle), _menuF(menuTitleF), _isSeparator(false), _isGroupTitle(!specialFunc), _requiresData(requiresData), _icon(icon), _specialFunc(specialFunc) {} AnalysisEntry::AnalysisEntry(std::string menuTitle, std::string icon, bool smallIcon) diff --git a/Desktop/modules/analysisentry.h b/Desktop/modules/analysisentry.h index cc773ebf2e..3545861925 100644 --- a/Desktop/modules/analysisentry.h +++ b/Desktop/modules/analysisentry.h @@ -39,12 +39,12 @@ class AnalysisEntry { friend EntryBase; public: - AnalysisEntry(std::function specialFunc, std::string internalTitle, std::string menuTitle, bool requiresData=true, std::string icon = ""); ///< AnalysisEntry with a callbackfunction to JASP, if !specialFunc then a grouptitle + AnalysisEntry(std::function specialFunc, std::string internalTitle, std::function menuTitleF, bool requiresData=true, std::string icon = ""); ///< AnalysisEntry with a callbackfunction to JASP, if !specialFunc then a grouptitle AnalysisEntry(std::string menuTitle, std::string icon = "", bool small=false); ///< AnalysisEntry grouptitle AnalysisEntry(Json::Value & analysisEntry, DynamicModule * dynamicModule, bool defaultRequiresData = true); ///< AnalysisEntry from a modules Description.qml AnalysisEntry(); ///< AnalysisEntry separator - std::string menu() const { return _menu; } + std::string menu() const { return _menuF ? _menuF() : _menu; } std::string title() const { return _title; } std::string function() const { return _function; } std::string qml() const { return _qml != "" ? _qml : _function + ".qml"; } @@ -75,20 +75,21 @@ class AnalysisEntry static bool requiresDataEntries(const AnalysisEntries & entries); private: - std::string _title = "???" , - _function = "???" , - _qml = "???" , - _menu = "???" , - _icon = "" ; - DynamicModule* _dynamicModule = nullptr ; - bool _isSeparator = true , - _isGroupTitle = false , - _isAnalysis = false , - _isEnabled = true , - _requiresData = true , - _hasWrapper = false , - _smallIcon = false ; - std::function _specialFunc = nullptr ; + std::string _title = "???" , + _function = "???" , + _qml = "???" , + _menu = "???" , + _icon = "" ; + DynamicModule* _dynamicModule = nullptr ; + bool _isSeparator = true , + _isGroupTitle = false , + _isAnalysis = false , + _isEnabled = true , + _requiresData = true , + _hasWrapper = false , + _smallIcon = false ; + std::function _specialFunc = nullptr ; + std::function _menuF = nullptr ; //To make it translatable }; } diff --git a/Desktop/modules/dynamicmodule.cpp b/Desktop/modules/dynamicmodule.cpp index 0c3617fcbd..5dcd7190fa 100644 --- a/Desktop/modules/dynamicmodule.cpp +++ b/Desktop/modules/dynamicmodule.cpp @@ -392,6 +392,7 @@ Json::Value DynamicModule::requestJsonForPackageLoadingRequest() requestJson["moduleRequest"] = moduleStatusToString(moduleStatus::loading); requestJson["moduleName"] = _name; + requestJson["moduleLibPaths"] = getLibPathsToUse(); requestJson["moduleCode"] = generateModuleLoadingR(); return requestJson; @@ -399,7 +400,7 @@ Json::Value DynamicModule::requestJsonForPackageLoadingRequest() std::string DynamicModule::getLibPathsToUse() const { - return "c('" + AppDirs::rHome().toStdString() + "/library', '" + shortenWinPaths(moduleRLibrary()).toStdString() + "')"; + return "c('" + shortenWinPaths(moduleRLibrary()).toStdString() + "', '" + AppDirs::rHome().toStdString() + "/library')"; } ///It would probably be better to move all of this code to jasp-r-pkg or something, but for now this works fine. @@ -427,17 +428,30 @@ std::string DynamicModule::generateModuleInstallingR(bool onlyModPkg) return "stop('Something went wrong during intialization of the Description!\nMake sure it follows the standard set in https://github.com/jasp-stats/jasp-desktop/blob/development/Docs/development/jasp-adding-module.md#descriptionqml\n')"; } setInstallLog("Installing module " + _name + ".\n"); - - return "options(\"renv.config.install.verbose\" = FALSE);jaspBase::installJaspModule(modulePkg='" + _modulePackage + "', libPathsToUse=" + getLibPathsToUse() + ", moduleLibrary='" + moduleRLibrary().toStdString() + - "', repos='" + Settings::value(Settings::CRAN_REPO_URL).toString().toStdString() + "', onlyModPkg=" + (onlyModPkg ? "TRUE" : "FALSE") + - ", force=TRUE, cacheAble=FALSE, frameworkLibrary='"+fq(AppDirs::rHome())+"/library');"; + return QString( + R"readableR( + tmp <- .libPaths(); + .libPaths("%1"); + Sys.setenv(MODULE_INSTALL_MODE="localizeModuleOnly"); + options("renv.config.install.verbose" = TRUE, "PKGDEPENDS_LIBRARY"="%2"); + result <- jaspModuleInstaller::installJaspModule(modulePkg='%3', moduleLibrary='%4', repos='%5', onlyModPkg=%6, force=TRUE, frameworkLibrary='%7'); + .libPaths(tmp); + return(result); + )readableR") + .arg(AppDirs::bundledModulesDir() + "Tools/jaspModuleInstaller_library/") + .arg(AppDirs::bundledModulesDir() + "Tools/pkgdepends_library/") + .arg(tq(_modulePackage)) + .arg(moduleRLibrary()) + .arg(Settings::value(Settings::CRAN_REPO_URL).toString()) + .arg(onlyModPkg ? "TRUE" : "FALSE") + .arg(AppDirs::rHome()+"/library") + .toStdString(); } std::string DynamicModule::generateModuleLoadingR(bool shouldReturnSucces) { std::stringstream R; - R << ".libPaths(" << getLibPathsToUse() <<");\n"; R << standardRIndent << "library('" << _name << "');\n"; if(shouldReturnSucces) diff --git a/Desktop/modules/dynamicmodules.cpp b/Desktop/modules/dynamicmodules.cpp index 858af0c1d7..b9fde87ea6 100644 --- a/Desktop/modules/dynamicmodules.cpp +++ b/Desktop/modules/dynamicmodules.cpp @@ -725,7 +725,7 @@ void DynamicModules::devModWatchFolder(QString folder, QFileSystemWatcher * & wa dstFile.remove(); } - connect(watcher, &QFileSystemWatcher::fileChanged, [=](const QString & path) + connect(watcher, &QFileSystemWatcher::fileChanged, [&](const QString & path) { //If only a file changes then update this single file QFileInfo srcFileChanged(path); @@ -739,7 +739,7 @@ void DynamicModules::devModWatchFolder(QString folder, QFileSystemWatcher * & wa if(folder == "help") emit this->reloadHelpPage(); }); - connect(watcher, &QFileSystemWatcher::directoryChanged, [=, &watcher](QString path) + connect(watcher, &QFileSystemWatcher::directoryChanged, [&](QString path) { Log::log() << "Watched folder " << folder.toStdString() << " had a changed directory (file added or removed) on path: " << path.toStdString() << std::endl; diff --git a/Desktop/modules/ribbonbutton.cpp b/Desktop/modules/ribbonbutton.cpp index ed9c558c7a..81ff3fad82 100644 --- a/Desktop/modules/ribbonbutton.cpp +++ b/Desktop/modules/ribbonbutton.cpp @@ -17,7 +17,6 @@ // #include "ribbonbutton.h" -#include "enginedefinitions.h" #include "modules/dynamicmodule.h" #include "modules/analysisentry.h" #include "utilities/qutils.h" @@ -49,14 +48,14 @@ RibbonButton::RibbonButton(QObject *parent, DynamicModule * module) : QObject(p bindYourself(); } -RibbonButton::RibbonButton(QObject *parent, std::string name, std::string title, std::string icon, bool requiresData, std::function justThisFunction, std::string toolTip, bool enabled, bool remember, bool defaultActiveBinding) +RibbonButton::RibbonButton(QObject *parent, std::string name, std::function titleF, std::string icon, bool requiresData, std::function justThisFunction, std::function toolTipF, bool enabled, bool remember, bool defaultActiveBinding) : QObject(parent), _enabled(enabled), _defaultActiveBinding(defaultActiveBinding), _remember(remember), _special(true), _module(nullptr), _specialButtonFunc(justThisFunction) { _menuModel = new MenuModel(this); setModuleName(name); - setTitle(title); - setToolTip(tq(toolTip)); + _titleF = titleF; + _toolTipF = toolTipF; setIconSource(tq(icon)); setRequiresData(requiresData); //setRequiresData because setMenu changes it based on the menu entries, but that doesnt work for this special dummy @@ -64,16 +63,16 @@ RibbonButton::RibbonButton(QObject *parent, std::string name, std::string title, bindYourself(); } -RibbonButton::RibbonButton(QObject *parent, std::string name, std::string title, std::string icon, Modules::AnalysisEntries * funcEntries, std::string toolTip, bool enabled, bool remember, bool defaultActiveBinding) +RibbonButton::RibbonButton(QObject *parent, std::string name, std::function titleF, std::string icon, Modules::AnalysisEntries * funcEntries, std::function toolTipF, bool enabled, bool remember, bool defaultActiveBinding) : QObject(parent), _enabled(enabled), _defaultActiveBinding(defaultActiveBinding), _remember(remember), _special(true), _module(nullptr) { _menuModel = new MenuModel(this, funcEntries); setRequiresData(AnalysisEntry::requiresDataEntries(*funcEntries)); setModuleName(name); - setTitle(title); + _titleF = titleF; + _toolTipF = toolTipF; setIconSource(tq(icon)); - setToolTip(tq(toolTip)); bindYourself(); } @@ -150,8 +149,6 @@ void RibbonButton::setReady(bool ready) setEnabled(true); } - - RibbonButton::~RibbonButton() { @@ -170,9 +167,9 @@ void RibbonButton::bindYourself() if (_defaultActiveBinding) { setActiveDefault(); - connect(this, &RibbonButton::enabledChanged, [=]() { setActiveDefault(); }); - connect(this, &RibbonButton::dataLoadedChanged, [=]() { setActiveDefault(); }); - connect(this, &RibbonButton::requiresDataChanged, [=]() { setActiveDefault(); }); + connect(this, &RibbonButton::enabledChanged, [&]() { setActiveDefault(); }); + connect(this, &RibbonButton::dataLoadedChanged, [&]() { setActiveDefault(); }); + connect(this, &RibbonButton::requiresDataChanged, [&]() { setActiveDefault(); }); } connect(DynamicModules::dynMods(), &DynamicModules::dataLoadedChanged, this, &RibbonButton::dataLoadedChanged ); @@ -291,6 +288,15 @@ void RibbonButton::setToolTip(QString toolTip) emit toolTipChanged(_toolTip); } +void RibbonButton::setToolTipF(std::function toolTipF) +{ + if ((!_toolTipF && !toolTipF) || (_toolTipF && toolTipF && _toolTipF() == toolTipF())) + return; + + _toolTipF = toolTipF; + emit toolTipChanged(_toolTipF()); +} + bool RibbonButton::separator() const { return _separator; diff --git a/Desktop/modules/ribbonbutton.h b/Desktop/modules/ribbonbutton.h index c168e21f74..6c90bcab19 100644 --- a/Desktop/modules/ribbonbutton.h +++ b/Desktop/modules/ribbonbutton.h @@ -56,15 +56,15 @@ class RibbonButton : public QObject RibbonButton(QObject *parent); RibbonButton(QObject *parent, Modules::DynamicModule * module); - RibbonButton(QObject *parent, std::string name, std::string title, std::string icon, bool requiresData, std::function justThisFunction, std::string toolTip = "", bool enabled = true, bool remember = false, bool defaultActiveBinding = true); - RibbonButton(QObject *parent, std::string name, std::string title, std::string icon, Modules::AnalysisEntries * funcEntries, std::string toolTip = "", bool enabled = true, bool remember = false, bool defaultActiveBinding = true); + RibbonButton(QObject *parent, std::string name, std::function titleF, std::string icon, bool requiresData, std::function justThisFunction, std::function toolTipF = [](){return "";}, bool enabled = true, bool remember = false, bool defaultActiveBinding = true); + RibbonButton(QObject *parent, std::string name, std::function titleF, std::string icon, Modules::AnalysisEntries * funcEntries, std::function toolTipF = [](){return "";}, bool enabled = true, bool remember = false, bool defaultActiveBinding = true); ~RibbonButton(); bool requiresData() const { return _requiresData; } bool isCommon() const { return _isCommonModule; } - std::string title() const { return _title; } - QString titleQ() const { return QString::fromStdString(_title); } + std::string title() const { return _titleF ? _titleF() : _title; } + QString titleQ() const { return QString::fromStdString(title()); } QString iconSource() const { return _iconSource; } bool enabled() const { return _enabled; } std::string name() const { return _name; } @@ -75,7 +75,7 @@ class RibbonButton : public QObject stringvec getAllEntries() const; bool dataLoaded() const { return Modules::DynamicModules::dynMods() && Modules::DynamicModules::dynMods()->dataLoaded(); } bool active() const { return _active; } - QString toolTip() const { return _toolTip; } + QString toolTip() const { return _toolTipF ? _toolTipF() : _toolTip; } bool isBundled() const { return _module && _module->isBundled(); } QString version() const { return !_module ? "?" : _module->versionQ(); } bool ready() const { return _ready; } @@ -83,31 +83,31 @@ class RibbonButton : public QObject bool remember() const { return _remember; } bool isSpecial() const { return _special; } - static QString getJsonDescriptionFilename(); + static QString getJsonDescriptionFilename(); bool separator() const; void setSeparator(bool newSeparator); + public slots: - void setDynamicModule(Modules::DynamicModule * module); - void setRequiresData(bool requiresData); - void setIsCommon(bool isCommonModule); - void setTitle(std::string title); - void setTitleQ(QString title) { setTitle(title.toStdString()); } - void setIconSource(QString iconSource); - void setEnabled(bool enabled); - void setModuleName(std::string moduleName); - void setModuleNameQ(QString moduleName) { setModuleName(moduleName.toStdString()); } - void somePropertyChanged() { emit iChanged(this); } - void setToolTip(QString toolTip); - void setReady(bool ready); - void setError(bool error); - void setRemember(bool remember); - void setActive(bool active); - - - void runSpecial(QString func);; - void reloadDynamicModule(Modules::DynamicModule * dynMod); + void setDynamicModule( Modules::DynamicModule * module); + void setRequiresData( bool requiresData); + void setIsCommon( bool isCommonModule); + void setTitle( std::string title); + void setTitleQ( QString title) { setTitle(title.toStdString()); } + void setIconSource( QString iconSource); + void setEnabled( bool enabled); + void setModuleName( std::string moduleName); + void setModuleNameQ( QString moduleName) { setModuleName(moduleName.toStdString()); } + void somePropertyChanged() { emit iChanged(this); } + void setToolTip( QString toolTip); + void setToolTipF( std::function toolTipF); + void setReady( bool ready); + void setError( bool error); + void setRemember( bool remember); + void setActive( bool active); + void runSpecial( QString func); + void reloadDynamicModule( Modules::DynamicModule * dynMod); signals: @@ -152,6 +152,8 @@ public slots: QString _iconSource, _toolTip; std::function _specialButtonFunc = nullptr; + std::function _titleF = nullptr; + std::function _toolTipF = nullptr; }; diff --git a/Desktop/modules/ribbonmodel.cpp b/Desktop/modules/ribbonmodel.cpp index 8d20f5168e..22db4f3a7f 100644 --- a/Desktop/modules/ribbonmodel.cpp +++ b/Desktop/modules/ribbonmodel.cpp @@ -38,6 +38,7 @@ RibbonModel::RibbonModel() : QAbstractListModel(DynamicModules::dynMods()) connect(DynamicModules::dynMods(), &DynamicModules::dynamicModuleUninstalled, this, &RibbonModel::removeDynamicRibbonButtonModel ); connect(DynamicModules::dynMods(), &DynamicModules::dynamicModuleReplaced, this, &RibbonModel::dynamicModuleReplaced ); connect(DynamicModules::dynMods(), &DynamicModules::dynamicModuleChanged, this, &RibbonModel::dynamicModuleChanged ); + connect(PreferencesModel::prefs(), &PreferencesModel::languageCodeChanged, this, &RibbonModel::refreshButtons ); } void RibbonModel::loadModules(std::vector commonModulesToLoad, std::vector extraModulesToLoad) @@ -120,42 +121,41 @@ void RibbonModel::addSpecialRibbonButtonsEarly() //_entriesInsert and _entriesDelete are destroyed by the menumodel destructor when the button gets destroyed. _entriesInsert = new AnalysisEntries( { - new AnalysisEntry([&](){ emit this->dataInsertRowBefore( -1); }, "insert-row-before", fq(tr("Insert row above")), true, "menu-row-insert-before"), - new AnalysisEntry([&](){ emit this->dataInsertRowAfter( -1); }, "insert-row-after", fq(tr("Insert row below")), true, "menu-row-insert-after"), + new AnalysisEntry([&](){ emit this->dataInsertRowBefore( -1); }, "insert-row-before", [&](){ return fq(tr("Insert row above"));}, true, "menu-row-insert-before"), + new AnalysisEntry([&](){ emit this->dataInsertRowAfter( -1); }, "insert-row-after", [&](){ return fq(tr("Insert row below"));}, true, "menu-row-insert-after"), new AnalysisEntry(), - new AnalysisEntry([&](){ emit this->dataInsertColumnBefore( -1,false,false); }, "insert-column-before", fq(tr("Insert column before")), true, "menu-column-insert-before"), - new AnalysisEntry([&](){ emit this->dataInsertColumnAfter( -1,false,false); }, "insert-column-after", fq(tr("Insert column after")), true, "menu-column-insert-after"), + new AnalysisEntry([&](){ emit this->dataInsertColumnBefore( -1,false,false); }, "insert-column-before", [&](){ return fq(tr("Insert column before"));}, true, "menu-column-insert-before"), + new AnalysisEntry([&](){ emit this->dataInsertColumnAfter( -1,false,false); }, "insert-column-after", [&](){ return fq(tr("Insert column after"));}, true, "menu-column-insert-after"), new AnalysisEntry(), - new AnalysisEntry([&](){ emit this->dataInsertColumnBefore( -1,true ,false); }, "insert-c-column-before", fq(tr("Insert constructor column before")), true, "menu-column-insert-before"), - new AnalysisEntry([&](){ emit this->dataInsertColumnAfter( -1,true ,false); }, "insert-c-column-after", fq(tr("Insert constructor column after")), true, "menu-column-insert-after"), - new AnalysisEntry([&](){ emit this->dataInsertColumnBefore( -1,true ,true); }, "insert-r-column-before", fq(tr("Insert R column before")), true, "menu-column-insert-before"), - new AnalysisEntry([&](){ emit this->dataInsertColumnAfter( -1,true ,true); }, "insert-r-column-after", fq(tr("Insert R column after")), true, "menu-column-insert-after"), + new AnalysisEntry([&](){ emit this->dataInsertColumnBefore( -1,true ,false); }, "insert-c-column-before", [&](){ return fq(tr("Insert constructor column before"));}, true, "menu-column-insert-before"), + new AnalysisEntry([&](){ emit this->dataInsertColumnAfter( -1,true ,false); }, "insert-c-column-after", [&](){ return fq(tr("Insert constructor column after"));}, true, "menu-column-insert-after"), + new AnalysisEntry([&](){ emit this->dataInsertColumnBefore( -1,true ,true); }, "insert-r-column-before", [&](){ return fq(tr("Insert R column before"));}, true, "menu-column-insert-before"), + new AnalysisEntry([&](){ emit this->dataInsertColumnAfter( -1,true ,true); }, "insert-r-column-after", [&](){ return fq(tr("Insert R column after"));}, true, "menu-column-insert-after"), }); _entriesDelete = new AnalysisEntries( { - new AnalysisEntry([&](){ emit this->dataRemoveColumn(); }, "delete-column", fq(tr("Delete column")), true, "menu-column-remove"), - new AnalysisEntry([&](){ emit this->dataRemoveRow(); }, "delete-row", fq(tr("Delete row")), true, "menu-row-remove"), - new AnalysisEntry([&](){ emit this->cellsClear(); }, "clear-cells", fq(tr("Clear cells")), true, "menu-cells-clear") + new AnalysisEntry([&](){ emit this->dataRemoveColumn(); }, "delete-column", [&](){ return fq(tr("Delete column"));}, true, "menu-column-remove"), + new AnalysisEntry([&](){ emit this->dataRemoveRow(); }, "delete-row", [&](){ return fq(tr("Delete row"));}, true, "menu-row-remove"), + new AnalysisEntry([&](){ emit this->cellsClear(); }, "clear-cells", [&](){ return fq(tr("Clear cells"));}, true, "menu-cells-clear") }); _entriesSynchOn = new AnalysisEntries( { - new AnalysisEntry([&]() { MainWindow::singleton()->startDataEditorHandler(); }, "open-datafile", fq(tr("Open datafile with default spreadsheet editor")), true, ""), - new AnalysisEntry([&]() { emit setDataSynchronisation(false); }, "stop-externaledit", fq(tr("Turn external data synchronisation off")), true, "") + new AnalysisEntry([&]() { MainWindow::singleton()->startDataEditorHandler(); }, "open-datafile", [](){ return fq(tr("Open datafile with default spreadsheet editor"));}, true, ""), + new AnalysisEntry([&]() { emit setDataSynchronisation(false); }, "stop-externaledit", [](){ return fq(tr("Turn external data synchronisation off"));}, true, "") }); - _analysesButton = new RibbonButton(this, "Analyses", fq(tr("Analyses")), "JASP_logo_green.svg", false, [&](){ emit finishCurrentEdit(); emit showStatistics(); }, fq(tr("Switch JASP to analyses mode")), true); - _dataSwitchButton = new RibbonButton(this, "Data", fq(tr("Edit Data")), "data-button.svg", false, [&](){ emit showData(); }, fq(tr("Switch JASP to data editing mode")), false, false, false); - _dataNewButton = new RibbonButton(this, "Data-New", fq(tr("New Data")), "data-button-new.svg", false, [&](){ emit genShowEmptyData(); }, fq(tr("Open a workspace without data")), true, false, false); - _dataResizeButton = new RibbonButton(this, "Data-Resize", fq(tr("Resize Data")), "data-button-resize.svg", false, [&](){ emit resizeData(); }, fq(tr("Resize your dataset")), false); - _insertButton = new RibbonButton(this, "Data-Insert", fq(tr("Insert")), "data-button-insert.svg", _entriesInsert, fq(tr("Insert empty columns or rows"))); - _removeButton = new RibbonButton(this, "Data-Remove", fq(tr("Remove")), "data-button-erase.svg", _entriesDelete, fq(tr("Remove columns or rows"))); - _synchroniseOnButton = new RibbonButton(this, "Data-Synch-On", fq(tr("Synchronisation")), "data-button-sync-off.svg", true, [&](){ emit setDataSynchronisation(true); }, fq(tr("Turn external data synchronisation on")), false); - _synchroniseOffButton = new RibbonButton(this, "Data-Synch-Off", fq(tr("Synchronisation")), "data-button-sync-on.svg", _entriesSynchOn, fq(tr("Turn external data synchronisation off")), true); - - _undoButton = new RibbonButton(this, "Data-Undo", fq(tr("Undo")), "menu-undo.svg", true, [&](){ emit dataUndo(); }, fq(tr("Undo changes, %1+Z").arg(getShortCutKey())), true, false, false); - _redoButton = new RibbonButton(this, "Data-Redo", fq(tr("Redo")), "menu-redo.svg", true, [&](){ emit dataRedo(); }, fq(tr("Redo changes, %1+shift+Z or %1+Y").arg(getShortCutKey())), true, false, false); + _analysesButton = new RibbonButton(this, "Analyses", [&](){ return fq(tr("Analyses"));}, "JASP_logo_green.svg", false, [&](){ emit finishCurrentEdit(); emit showStatistics(); }, [&](){return tr("Switch JASP to analyses mode");}, true); + _dataSwitchButton = new RibbonButton(this, "Data", [&](){ return fq(tr("Edit Data"));}, "data-button.svg", false, [&](){ emit showData(); }, [&](){return tr("Switch JASP to data editing mode");}, false, false, false); + _dataNewButton = new RibbonButton(this, "Data-New", [&](){ return fq(tr("New Data"));}, "data-button-new.svg", false, [&](){ emit showNewData(); }, [&](){return tr("Open a workspace without data");}, true, false, false); + _dataResizeButton = new RibbonButton(this, "Data-Resize", [&](){ return fq(tr("Resize Data"));}, "data-button-resize.svg", false, [&](){ emit resizeData(); }, [&](){return tr("Resize your dataset");}, false); + _insertButton = new RibbonButton(this, "Data-Insert", [&](){ return fq(tr("Insert"));}, "data-button-insert.svg", _entriesInsert, [&](){return tr("Insert empty columns or rows");}); + _removeButton = new RibbonButton(this, "Data-Remove", [&](){ return fq(tr("Remove"));}, "data-button-erase.svg", _entriesDelete, [&](){return tr("Remove columns or rows");}); + _synchroniseOnButton = new RibbonButton(this, "Data-Synch-On", [&](){ return fq(tr("Synchronisation"));}, "data-button-sync-off.svg", true, [&](){ emit setDataSynchronisation(true); }, [&](){return tr("Turn external data synchronisation on");}, false); + _synchroniseOffButton = new RibbonButton(this, "Data-Synch-Off", [&](){ return fq(tr("Synchronisation"));}, "data-button-sync-on.svg", _entriesSynchOn, [&](){return tr("Turn external data synchronisation off");}, true); + _undoButton = new RibbonButton(this, "Data-Undo", [&](){ return fq(tr("Undo"));}, "menu-undo.svg", true, [&](){ emit dataUndo(); }, [&](){return tr("Undo changes, %1+Z").arg(getShortCutKey());}, true, false, false); + _redoButton = new RibbonButton(this, "Data-Redo", [&](){ return fq(tr("Redo"));}, "menu-redo.svg", true, [&](){ emit dataRedo(); }, [&](){return tr("Redo changes, %1+shift+Z or %1+Y").arg(getShortCutKey());}, true, false, false); _dataNewButton->setActive(true); connect(this, &RibbonModel::dataLoadedChanged, _dataSwitchButton, [=](bool loaded) { _dataSwitchButton ->setEnabled(loaded); }); @@ -173,14 +173,11 @@ void RibbonModel::addSpecialRibbonButtonsEarly() auto setUnAndRedoButtonLambda = [&,view]() { - QString undoText = view->undoText(), - redoText = view->redoText(); - - _undoButton->setActive(!undoText.isEmpty()); - _redoButton->setActive(!redoText.isEmpty()); + _undoButton->setActive(!view->undoText().isEmpty()); + _redoButton->setActive(!view->redoText().isEmpty()); - _undoButton->setToolTip(tr("Undo %2 (%1+Z)") .arg(getShortCutKey()).arg(undoText)); - _redoButton->setToolTip(tr("Redo %2 (%1+shift+Z or %1+Y)") .arg(getShortCutKey()).arg(redoText)); + _undoButton->setToolTipF([&,view](){return tr("Undo %2 (%1+Z)") .arg(getShortCutKey()).arg(view->undoText());}); + _redoButton->setToolTipF([&,view](){return tr("Redo %2 (%1+shift+Z or %1+Y)") .arg(getShortCutKey()).arg(view->redoText());}); }; @@ -207,7 +204,7 @@ void RibbonModel::addSpecialRibbonButtonsEarly() void RibbonModel::addSpecialRibbonButtonsLate() { - addRibbonButtonModel(new RibbonButton(this, "R", fq(tr("R console")), "Rlogo.svg", false, [&](){ emit showRCommander(); }, fq(tr("Execute R code in a console")), false, true), size_t(RowType::Analyses)); + addRibbonButtonModel(new RibbonButton(this, "R", [&](){return fq(tr("R console")); }, "Rlogo.svg", false, [&](){ emit showRCommander(); }, [&](){ return tr("Execute R code in a console");}, false, true), size_t(RowType::Analyses)); } void RibbonModel::setDataMode(bool data) @@ -455,3 +452,9 @@ void RibbonModel::ribbonButtonModelChanged(RibbonButton* model) if(row > -1) emit dataChanged(index(row), index(row)); } + +void RibbonModel::refreshButtons() +{ + beginResetModel(); + endResetModel(); +} diff --git a/Desktop/modules/ribbonmodel.h b/Desktop/modules/ribbonmodel.h index 94aceea947..e37c6369bf 100644 --- a/Desktop/modules/ribbonmodel.h +++ b/Desktop/modules/ribbonmodel.h @@ -72,7 +72,6 @@ class RibbonModel : public QAbstractListModel void setDataMode(bool data); Q_INVOKABLE void showData() { setCurrentRow(int(RowType::Data)); } Q_INVOKABLE void showStatistics() { setCurrentRow(int(RowType::Analyses)); } - void genShowEmptyData() { generateEmptyData(); showData(); } void removeRibbonButtonModel(std::string moduleName); @@ -105,7 +104,6 @@ class RibbonModel : public QAbstractListModel void invalidateFilterModel(); void currentRowChanged(); void dataLoadedChanged(bool loaded); - void generateEmptyData(); void dataModeChanged(bool dataMode); void startExternalEdit(); void stopExternalEdit(); @@ -124,6 +122,7 @@ class RibbonModel : public QAbstractListModel void cellsClear(); void dataUndo(); void dataRedo(); + void showNewData(); public slots: void addRibbonButtonModelFromDynamicModule(Modules::DynamicModule * module); @@ -131,7 +130,7 @@ public slots: void setHighlightedModuleIndex(int highlightedModuleIndex); void analysisClicked(QString analysisFunction, QString analysisQML, QString analysisTitle, QString module); void setCurrentRow(int currentRow); - + void refreshButtons(); private slots: void dynamicModuleChanged( Modules::DynamicModule * module); diff --git a/Desktop/po/jaspDesktop-de.po b/Desktop/po/jaspDesktop-de.po index 27aec0c3d7..327b4a13e6 100644 --- a/Desktop/po/jaspDesktop-de.po +++ b/Desktop/po/jaspDesktop-de.po @@ -2912,7 +2912,7 @@ msgid "" "href=\"http://%6\">%6
    " msgstr "" "

    %1

    Version %2

    %3



    Erstellt von %4 und " -"gepflegt von %5.
    Siehe Website für weitere Details:
    Siehe Webseite für weitere Details:
    %6
    " #, qt-format @@ -4828,7 +4828,7 @@ msgstr "" "JASP-Forum.\n" "\n" "Für Informationen zur JASP-Gemeinschaft: Lesen Sie bitte die " -"Informationen auf der JASP-Website\n" +"Informationen auf der JASP-Webseite\n" "\n" "Um vorzuschlagen, dass wir Ihre Einrichtung zur JASP-" "Weltkarte hinzufügen, senden Sie bitte eine E-Mail an Click here for the current list of educators\n" msgstr "" "

    Gemeinschaft

    \n" -"The Institutionen der höheren Bildung, die sich an der JASP-Gemeinschaft " +"Die Institutionen der höheren Bildung, die sich an der JASP-Gemeinschaft " "beteiligen, unterstützen gemeinsam die Wartung und Weiterentwicklung von " "JASP und bieten damit einen unschätzbaren Bildungsdienst für ihre eigenen " "Studierenden und die anderer Institutionen weltweit.\n" @@ -5454,7 +5454,6 @@ msgctxt "ListModelTermsAssigned|" msgid "Only %1 variables are allowed" msgstr "Nur %1 Variablen sind erlaubt" -#, fuzzy msgctxt "VariableInfo|" msgid "Scale" msgstr "Metrisch" @@ -5473,11 +5472,12 @@ msgstr "Unbekannt" msgctxt "ColumnBasicInfo|" msgid "" -msgstr "" +msgstr "" msgctxt "PrefsData|" msgid "Maximum allowed levels for scale when used as nominal/ordinal" msgstr "" +"Maximal erlaubte Stufen für Metrisch bei Verwendung als Nominal/Ordinal" msgctxt "PrefsData|" msgid "" @@ -5485,11 +5485,14 @@ msgid "" "scale variable is used, JASP checks whether the number of levels of this " "variable exceeds this maximum." msgstr "" +"Bei Analysen, die nur nominale oder ordinale Variablen akzeptieren, prüft " +"JASP bei Verwendung einer metrischen Variablen, ob die Stufenanzahl dieser " +"Variablen dieses Maximum überschreitet." #, qt-format msgctxt "VariablesListBase|" msgid "Maximum number of levels is %1. Variable %2 has %3 levels." -msgstr "" +msgstr "Maximale Anzahl von Stufen ist %1. Die Variable %2 hat %3 Stufen." #, qt-format msgctxt "VariablesListBase|" @@ -5499,6 +5502,11 @@ msgid "" "either change its type, or change 'Maximum allowed levels for scale' in " "Preferences / Data menu" msgstr "" +"Es wurde versucht, die metrische Variable %1 in eine %2-Variable " +"umzuwandeln, aber die Anzahl der Stufen %3 überschreitet das Maximum %4. " +"Wenn Sie diese Variable dennoch verwenden möchten, ändern Sie entweder ihren " +"Typ oder ändern Sie die \"Maximal zulässigen Stufen für Metrisch\" im Menü " +"Einstellungen / Daten" #, qt-format msgctxt "VariablesListBase|" @@ -5506,3 +5514,56 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" +"Die minimale Anzahl von numerischen Werten ist %1. Variable %2 hat nur %3 " +"verschiedene numerische Werte" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "Lade neuen Datensatz" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "Neu" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "Importiere Excel-Datei" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "Alle Datensätze %1" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "JASP-Dateien %1" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "CSV-Text-Dateien %1" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "Tabellen-Dateien %1" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "SPSS-Dateien %1" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "Stata-Dateien %1" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "SAS-Dateien %1" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-eo.po b/Desktop/po/jaspDesktop-eo.po index 06c0ebc4fe..604dd82d1c 100644 --- a/Desktop/po/jaspDesktop-eo.po +++ b/Desktop/po/jaspDesktop-eo.po @@ -5050,3 +5050,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-es.po b/Desktop/po/jaspDesktop-es.po index 2d3b4e8d92..ebbc2d2372 100644 --- a/Desktop/po/jaspDesktop-es.po +++ b/Desktop/po/jaspDesktop-es.po @@ -5478,11 +5478,12 @@ msgstr "Desconocido" msgctxt "ColumnBasicInfo|" msgid "" -msgstr "" +msgstr "" msgctxt "PrefsData|" msgid "Maximum allowed levels for scale when used as nominal/ordinal" msgstr "" +"Niveles de escala máximos permitidos cuando se usa como nominal/ordinal" msgctxt "PrefsData|" msgid "" @@ -5490,11 +5491,14 @@ msgid "" "scale variable is used, JASP checks whether the number of levels of this " "variable exceeds this maximum." msgstr "" +"Para los análisis que admiten solo que algunas variables sean nominales u " +"ordinales, cuando se usa una variable de escala, JASP comprueba si el número " +"de niveles de esta variable excede este máximo." #, qt-format msgctxt "VariablesListBase|" msgid "Maximum number of levels is %1. Variable %2 has %3 levels." -msgstr "" +msgstr "El número máximo de niveles es %1. La variable %2 tiene %3 niveles." #, qt-format msgctxt "VariablesListBase|" @@ -5504,6 +5508,10 @@ msgid "" "either change its type, or change 'Maximum allowed levels for scale' in " "Preferences / Data menu" msgstr "" +"Intenta transformar la variable de escala %1 en la variable %2, pero su " +"número de niveles %3 excede el máximo %4. Si todavía desea utilizar esta " +"variable, modifique su tipo o cambie 'Niveles de escala máximos permitidos' " +"en el menú de Preferencias/Datos" #, qt-format msgctxt "VariablesListBase|" @@ -5511,3 +5519,56 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" +"El número mínimo de valores numéricos es %1. La variable %2 tiene solo %3 " +"valores numéricos diferentes" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "Cargando Nuevo Conjunto de Datos" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "Nuevo" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "Importando archivo de Excel" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "Todos los conjuntos de datos %1" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "Archivos de JASP %1" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "Archivos de texto CSV %1" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "Archivos de hoja de cálculo %1" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "Archivos de SPSS %1" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "Archivos de Stata %1" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "Archivos de SAS %1" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-fr.po b/Desktop/po/jaspDesktop-fr.po index bb3ce6b4fe..65c011d139 100644 --- a/Desktop/po/jaspDesktop-fr.po +++ b/Desktop/po/jaspDesktop-fr.po @@ -5467,3 +5467,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-gl.po b/Desktop/po/jaspDesktop-gl.po index 72884ba7de..1596e8ae58 100644 --- a/Desktop/po/jaspDesktop-gl.po +++ b/Desktop/po/jaspDesktop-gl.po @@ -5452,11 +5452,11 @@ msgstr "Descoñecido" msgctxt "ColumnBasicInfo|" msgid "" -msgstr "" +msgstr "" msgctxt "PrefsData|" msgid "Maximum allowed levels for scale when used as nominal/ordinal" -msgstr "" +msgstr "Niveis de escala máximos permitidos cando se usa como nominal/ordinal" msgctxt "PrefsData|" msgid "" @@ -5464,11 +5464,14 @@ msgid "" "scale variable is used, JASP checks whether the number of levels of this " "variable exceeds this maximum." msgstr "" +"Para as análises que admiten só que algunhas variables sexan nominais ou " +"ordinais, cando se usa unha variable de escala, JASP comproba se o número de " +"niveis desta variable excede este máximo." #, qt-format msgctxt "VariablesListBase|" msgid "Maximum number of levels is %1. Variable %2 has %3 levels." -msgstr "" +msgstr "O número máximo de niveis é %1. A variable %2 ten %3 niveis." #, qt-format msgctxt "VariablesListBase|" @@ -5478,6 +5481,10 @@ msgid "" "either change its type, or change 'Maximum allowed levels for scale' in " "Preferences / Data menu" msgstr "" +"Intentas transformar a variable de escala %1 na variable %2, pero o seu " +"número de niveis %3 excede o máximo %4. Se aínda queres utilizar esta " +"variable, ben troca o seu tipo, ou ben troca 'Niveis de escala máximos " +"permitidos' no menú de Preferencias/Datos" #, qt-format msgctxt "VariablesListBase|" @@ -5485,3 +5492,56 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" +"O número mínimo de valores numéricos é %1. A variable %2 ten só %3 valores " +"numéricos diferentes" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "Cargando Novo Conxunto de Datos" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "Novo" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "Importando ficheiro de Excel" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "Tódolos conxuntos de datos %1" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "Ficheiros de JASP %1" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "Ficheiros de texto CSV %1" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "Ficheiros de folla de cálculo %1" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "Ficheiros de SPSS %1" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "Ficheiros de Stata %1" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "Ficheiros de SAS %1" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-hu.po b/Desktop/po/jaspDesktop-hu.po index 00ffa2a5c3..acc80c161b 100644 --- a/Desktop/po/jaspDesktop-hu.po +++ b/Desktop/po/jaspDesktop-hu.po @@ -1,7 +1,7 @@ msgid "" msgstr "" -"PO-Revision-Date: 2024-03-05 20:01+0000\n" -"Last-Translator: Horváth Péter \n" +"PO-Revision-Date: 2024-09-11 18:09+0000\n" +"Last-Translator: Salyámosy András \n" "Language-Team: Hungarian \n" "Language: hu\n" @@ -9,7 +9,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.5-dev\n" +"X-Generator: Weblate 5.8-dev\n" "X-Qt-Contexts: true\n" msgctxt "ComponentsList|" @@ -30,11 +30,11 @@ msgstr "Fájl betöltése innen:" msgctxt "FileSelector|" msgid "Select file to save" -msgstr "Menteni kívánt fájl kijelölése" +msgstr "Menteni kívánt fájl kiválasztása" msgctxt "FileSelector|" msgid "Select file to load" -msgstr "Megnyitni kívánt fájl kijelölése" +msgstr "Megnyitni kívánt fájl kiválasztása" msgctxt "FileSelector|" msgid "Browse" @@ -44,16 +44,20 @@ msgctxt "Form|" msgid "" "This analysis was created with an older version of JASP (or a dynamic module)" msgstr "" +"Ez az analízis a JASP (vagy egy dinamikus modul) egy korábbi verziójával " +"készült" msgctxt "Form|" msgid ", refreshing could give a slightly different result." -msgstr "" +msgstr ", a frissítése kissé eltérő eredményt adhat." msgctxt "Form|" msgid "" ", to keep your notes where they are it is highly recommended to first " "refresh your analyses!" msgstr "" +", javasolt frissítened az analízisedet, hogy a jegyzeteid a helyükön " +"maradjanak!" msgctxt "InputListView|" msgid "New Value" @@ -94,11 +98,11 @@ msgstr "Ctrl+Enter az alkalmazásra" #, qt-format msgctxt "TextField|" msgid "Restoring last correct value: %1" -msgstr "" +msgstr "Utolsó helyes érték helyreállítása: %1" msgctxt "VariablesForm|" msgid "Main Effects" -msgstr "" +msgstr "Fő hatások" msgctxt "VariablesForm|" msgid "Only 2 way" @@ -146,15 +150,15 @@ msgstr "Letöltés:" msgctxt "AboutWindow|" msgid "Citation:" -msgstr "" +msgstr "Idézet:" msgctxt "AboutWindow|" msgid "Select All" -msgstr "" +msgstr "Mindegyik kijelölése" msgctxt "AboutWindow|" msgid "Copy Selection" -msgstr "" +msgstr "Kijelölés másolása" msgctxt "AboutWindow|" msgid "BibTeX" @@ -162,43 +166,45 @@ msgstr "" msgctxt "AboutWindow|" msgid "Close" -msgstr "" +msgstr "Bezárás" msgctxt "AnalysisFormExpander|" msgid "Drag to reorder the analyses" -msgstr "" +msgstr "Húzd arréb az analízis átrendezéséhez" msgctxt "AnalysisFormExpander|" msgid "Edit the title of this analysis" -msgstr "" +msgstr "Az analízis címének szerkesztése" +#, fuzzy msgctxt "AnalysisFormExpander|" msgid "Duplicate this analysis" -msgstr "" +msgstr "Az analízis megduplázása" +#, fuzzy msgctxt "AnalysisFormExpander|" msgid "Show info for this analysis" -msgstr "" +msgstr "Információk megjelenítése erről az analízisről" msgctxt "AnalysisFormExpander|" msgid "Remove this analysis" -msgstr "" +msgstr "Analízis eltávolítása" msgctxt "AnalysisForms|" msgid "Resize data/results" -msgstr "" +msgstr "Adatok vagy eredmények átméretezése" msgctxt "AnalysisForms|" msgid "Drag to show data" -msgstr "" +msgstr "Húzd odébb az adatok megjelenítéséhez" msgctxt "AnalysisForms|" msgid "Hide input options" -msgstr "" +msgstr "Bemeneti beállítások elrejtése" msgctxt "AnalysisForms|" msgid "Show input options" -msgstr "" +msgstr "Bemeneti beállítások megjelenítése" msgctxt "BasicThreeButtonTableView|" msgid "Add" @@ -214,35 +220,41 @@ msgstr "Visszaállítás" msgctxt "BayesFactorType|" msgid "Bayes Factor" -msgstr "" +msgstr "Bayes faktor" msgctxt "BayesFactorType|" msgid "BF₁₀" -msgstr "" +msgstr "BF₁₀" +#, fuzzy msgctxt "BayesFactorType|" msgid "" "Bayes factor to quantify evidence for the alternative hypothesis relative to " "the null hypothesis." msgstr "" +"Bayes faktor az alternatív hipotézis null hipotézishez viszonyított " +"valószínűségének számszerűsítésére." msgctxt "BayesFactorType|" msgid "BF₀₁" -msgstr "" +msgstr "BF₀₁" +#, fuzzy msgctxt "BayesFactorType|" msgid "" "Bayes factor to quantify evidence for the null hypothesis relative to the " "alternative hypothesis." msgstr "" +"Bayes faktor a null hipotézis alternatív hipotézishez viszonyított " +"valószínűségének számszerűsítésére." msgctxt "BayesFactorType|" msgid "Log(BF₁₀)" -msgstr "" +msgstr "Log(BF₁₀)" msgctxt "BayesFactorType|" msgid "Natural logarithm of BF10." -msgstr "" +msgstr "A BF10 természetes logaritmusa." msgctxt "Chi2TestTableView|" msgid "Add Column" @@ -256,69 +268,70 @@ msgctxt "Chi2TestTableView|" msgid "Reset" msgstr "Visszaállítás" +#, fuzzy msgctxt "ComputeColumnWindow|" msgid "Computed Column: " -msgstr "" +msgstr "Számított oszlop: " msgctxt "ComputeColumnWindow|" msgid "Select a column" -msgstr "" +msgstr "Oszlop kiválasztása" msgctxt "ComputeColumnWindow|" msgid "absolute value" -msgstr "" +msgstr "abszolútérték" msgctxt "ComputeColumnWindow|" msgid "standard deviation" -msgstr "" +msgstr "normális eloszlás" msgctxt "ComputeColumnWindow|" msgid "variance" -msgstr "" +msgstr "variancia" msgctxt "ComputeColumnWindow|" msgid "summation" -msgstr "" +msgstr "összegzés" msgctxt "ComputeColumnWindow|" msgid "product of values" -msgstr "" +msgstr "értékek szorzata" msgctxt "ComputeColumnWindow|" msgid "returns minimum of values" -msgstr "" +msgstr "az értékek minimumát adja vissza" msgctxt "ComputeColumnWindow|" msgid "returns maximum of values" -msgstr "" +msgstr "az értékek maximumát adja vissza" msgctxt "ComputeColumnWindow|" msgid "mean" -msgstr "" +msgstr "átlag" msgctxt "ComputeColumnWindow|" msgid "rounds y to n decimals" -msgstr "" +msgstr "n tizedesjegyre kerekíti y-t" msgctxt "ComputeColumnWindow|" msgid "returns number of elements in y" -msgstr "" +msgstr "visszaadja az y-ban lévő elemek számát" msgctxt "ComputeColumnWindow|" msgid "median" -msgstr "" +msgstr "medián" msgctxt "ComputeColumnWindow|" msgid "natural logarithm" -msgstr "" +msgstr "természetes logaritmus" msgctxt "ComputeColumnWindow|" msgid "base 2 logarithm" -msgstr "" +msgstr "2-es alapú logaritmus" msgctxt "ComputeColumnWindow|" msgid "base 10 logarithm" -msgstr "" +msgstr "10-es alapú logaritmus" msgctxt "ComputeColumnWindow|" msgid "logarithm of y in 'base'" @@ -326,7 +339,7 @@ msgstr "" msgctxt "ComputeColumnWindow|" msgid "exponential" -msgstr "" +msgstr "exponenciális" msgctxt "ComputeColumnWindow|" msgid "" @@ -427,23 +440,23 @@ msgstr "" msgctxt "ComputeColumnWindow|" msgid "Remove computed column" -msgstr "" +msgstr "Számított oszlop eltávolítása" msgctxt "ComputeColumnWindow|" msgid "Show generated R code" -msgstr "" +msgstr "Generált R kód megjelenítése" msgctxt "ComputeColumnWindow|" msgid "Compute column" -msgstr "" +msgstr "Oszlop számítása" msgctxt "ComputeColumnWindow|" msgid "Column computed" -msgstr "" +msgstr "Oszlop számítása kész" msgctxt "ComputeColumnWindow|" msgid "Click to compute column" -msgstr "" +msgstr "Kattints ide az oszlop számításához" msgctxt "ComputeColumnWindow|" msgid "Column (in line to be) computed" @@ -451,21 +464,23 @@ msgstr "" msgctxt "ComputeColumnWindow|" msgid "Open Documentation" -msgstr "" +msgstr "Dokumentáció megnyitása" msgctxt "ComputeColumnWindow|" msgid "Close computed column window" -msgstr "" +msgstr "Számított oszlop ablak bezárása" msgctxt "ComputeColumnWindow|" msgid "Computed Column Changed" -msgstr "" +msgstr "Számított oszlop megváltozott" msgctxt "ComputeColumnWindow|" msgid "" "There are unapplied changes to your computed column; what would you like to " "do?" msgstr "" +"A számított oszlop nem mentett változtatásokat tartalmaz, mit szeretnél " +"csinálni?" msgctxt "ContrastsList|" msgid "none" @@ -473,15 +488,15 @@ msgstr "" msgctxt "ContrastsList|" msgid "deviation" -msgstr "" +msgstr "eloszlás" msgctxt "ContrastsList|" msgid "simple" -msgstr "" +msgstr "egyszerű" msgctxt "ContrastsList|" msgid "difference" -msgstr "" +msgstr "eltérés" msgctxt "ContrastsList|" msgid "Helmert" @@ -489,15 +504,15 @@ msgstr "" msgctxt "ContrastsList|" msgid "repeated" -msgstr "" +msgstr "ismételt" msgctxt "ContrastsList|" msgid "polynomial" -msgstr "" +msgstr "polinomiális" msgctxt "ContrastsList|" msgid "custom" -msgstr "" +msgstr "egyedi" msgctxt "ContrastsList|" msgid "Factors" @@ -510,23 +525,23 @@ msgstr "" msgctxt "CreateComputeColumnDialog|" msgid "Create Computed Column" -msgstr "" +msgstr "Számított oszlop létrehozása" msgctxt "CreateComputeColumnDialog|" msgid "Name:" -msgstr "" +msgstr "Név:" msgctxt "CreateComputeColumnDialog|" msgid "Column name is already used, please choose a different one." -msgstr "" +msgstr "Ez az oszlopnév már használatban van, válassz egy másikat!" msgctxt "CreateComputeColumnDialog|" msgid "Define column through R code" -msgstr "" +msgstr "Oszlop létrehozása R kód segítségével" msgctxt "CreateComputeColumnDialog|" msgid "Define column through drag and drop formulas" -msgstr "" +msgstr "Oszlop létrehozása húzd-és-vidd képlettel" msgctxt "CreateComputeColumnDialog|" msgid "Scale" @@ -542,28 +557,29 @@ msgstr "" msgctxt "CreateComputeColumnDialog|" msgid "Text" -msgstr "" +msgstr "Szöveg" msgctxt "CreateComputeColumnDialog|" msgid "Open Documentation" -msgstr "" +msgstr "Dokumentáció megnyitása" msgctxt "CreateComputeColumnDialog|" msgid "Create Column" -msgstr "" +msgstr "Oszlop létrehozása" #, qt-format msgctxt "CreateComputeColumnDialog|" msgid "Click here to create your new computed column '%1'" -msgstr "" +msgstr "Kattints ide az új számított oszlop létrehozásához '%1' néven" msgctxt "CreateComputeColumnDialog|" msgid "Enter a valid (unused) name for computed column" msgstr "" +"Adj meg egy érvényes (még nem használataban lévő) nevet a számított oszlopnak" msgctxt "CreateComputeColumnDialog|" msgid "Close without creating a computed column" -msgstr "" +msgstr "Bezárás számított oszlop létrehozása nélkül" msgctxt "CustomContrastsTableView|" msgid "Add Contrast" @@ -612,39 +628,39 @@ msgstr "" msgctxt "BreadCrumbs|" msgid "You are here" -msgstr "" +msgstr "Itt vagy most" msgctxt "Computer|" msgid "Recent Folders" -msgstr "" +msgstr "Nemrégiben megnyitott mappák" msgctxt "Computer|" msgid "Browse" -msgstr "" +msgstr "Tallózás" msgctxt "CurrentFile|" msgid "Current data file for synchronization" -msgstr "" +msgstr "A szinkronizálásához jelenleg használt adatfájl" msgctxt "DataLibrary|" msgid "Data Library" -msgstr "" +msgstr "Adatkönyvtár" msgctxt "ListItem|" msgid "Synchronize with this Data File" -msgstr "" +msgstr "Adatfájl szinkronizálása" msgctxt "ListItem|" msgid "Navigate to folder" -msgstr "" +msgstr "Mappa megnyitása" msgctxt "ListItem|" msgid "Open JASP file" -msgstr "" +msgstr "JASP fájl megnyitása" msgctxt "ListItem|" msgid "Open data file" -msgstr "" +msgstr "Adatfájl megnyitása" msgctxt "MenuHeader|" msgid "Show info about these preferences" @@ -656,23 +672,23 @@ msgstr "" msgctxt "OSF|" msgid "Logout" -msgstr "" +msgstr "Kijelentkezés" msgctxt "OSF|" msgid "Create Folder" -msgstr "" +msgstr "Mappa létrehozása" msgctxt "OSF|" msgid "Foldername" -msgstr "" +msgstr "Mappanév" msgctxt "OSF|" msgid "Filename" -msgstr "" +msgstr "Fájlnév" msgctxt "OSF|" msgid "Save" -msgstr "" +msgstr "Mentés" msgctxt "OSFLogin|" msgid "OSF" @@ -680,53 +696,56 @@ msgstr "" msgctxt "OSFLogin|" msgid "Sign in with your OSF account to continue" -msgstr "" +msgstr "Bejelentkezés OSF felhasználóval" msgctxt "OSFLogin|" msgid "Sign in" -msgstr "" +msgstr "Bejelentkezés" msgctxt "OSFLogin|" msgid "Remember me" -msgstr "" +msgstr "Emlékezz rám" msgctxt "OSFLogin|" msgid "About the OSF" -msgstr "" +msgstr "Az OSF-ről" msgctxt "OSFLogin|" msgid "Register" -msgstr "" +msgstr "Regisztáció" msgctxt "PrefsAdvanced|" msgid "Advanced Preferences" -msgstr "" +msgstr "Haladó beállítások" msgctxt "PrefsAdvanced|" msgid "Modules options" -msgstr "" +msgstr "Modul beállítások" msgctxt "PrefsAdvanced|" msgid "" "Continue where you left of the next time JASP starts.\n" "Enabling this option makes JASP remember which Modules you've enabled." msgstr "" +"Folytasd ott, ahol abbahagytad, amikor legközelebb elindul a JASP.\n" +"Ennek a kapcsolónak a bekapcsolása után a JASP emlékezni fog rá, hogy melyik " +"modulokat kapcsoltad be." msgctxt "PrefsAdvanced|" msgid "Developer mode (Beta version)" -msgstr "" +msgstr "Fejlesztői mód (béta verzió)" msgctxt "PrefsAdvanced|" msgid "To use JASP Modules enable this option." -msgstr "" +msgstr "A JASP modulok engedélyezéséhez kapcsold be ezt az opciót." msgctxt "PrefsAdvanced|" msgid "Select developer folder" -msgstr "" +msgstr "Fejlesztői mappa kiválasztása" msgctxt "PrefsAdvanced|" msgid "Browse to your JASP Module folder." -msgstr "" +msgstr "A JASP modul mappád megnyitása." msgctxt "PrefsAdvanced|" msgid "Change the CRAN repository: " @@ -734,12 +753,14 @@ msgstr "" msgctxt "PrefsAdvanced|" msgid "Generate markdown files for help" -msgstr "" +msgstr "Markdown súgó fájlok generálása" msgctxt "PrefsAdvanced|" msgid "" "Enabling this will generate markdown helpfile from the info at qml options." msgstr "" +"Ennek az opciónak a bekapcsolása markdown formátumú súgó fájlokat fog " +"generálni a qml beállításokból." msgctxt "PrefsAdvanced|" msgid "Windows workarounds" @@ -757,7 +778,7 @@ msgstr "" msgctxt "PrefsAdvanced|" msgid "See the documentation for more info." -msgstr "" +msgstr "Több információt a dokumentációban találsz." msgctxt "PrefsAdvanced|" msgid "" @@ -765,6 +786,10 @@ msgid "" "JASP won't work anymore. If you only have non-ascii characters in your " "username then installing modules will probably break." msgstr "" +"Ha bekapcsolod ezt az opciót, és a JASP-ot tartalmazó mappa elérési " +"útvonalában nem ASCII karakterek szerepelnek, a JASP nem fog működni. Ha " +"csak a felhasználói nevedben szerepelnek nem ASCII karakterek, valószínűleg " +"nem fogsz tudni JASP modulokat telepíteni." msgctxt "PrefsAdvanced|" msgid "" @@ -773,54 +798,58 @@ msgid "" "characters in the path. Sorry for the inconvenience, we are working on it " "and hopefully have this fixed next release." msgstr "" +"Ha bekapcsolod ezt az opciót, néhány karakter furán fog megjelenni a " +"kimenetben, de tudod majd használni a JASP-ot egy nem ASCII karakterket " +"tartalmazó mappából is. Elnézést kérünk a kényelmetlenségéert, és dolgozunk " +"azon, hogy ezt megjavítsuk a JASP következő kiadásában." msgctxt "PrefsAdvanced|" msgid "Logging options" -msgstr "" +msgstr "Logolással kapcsolatos beállítások" msgctxt "PrefsAdvanced|" msgid "Log to file" -msgstr "" +msgstr "Fájlba logolás" msgctxt "PrefsAdvanced|" msgid "To store debug-logs of JASP in a file, check this box." -msgstr "" +msgstr "A JASP debug logjainka fájlba való írásához kapcsold be ezt az opciót." msgctxt "PrefsAdvanced|" msgid "Max logfiles to keep: " -msgstr "" +msgstr "Logfájlok maximális száma: " msgctxt "PrefsAdvanced|" msgid "Show logs" -msgstr "" +msgstr "Logok megjelenítése" msgctxt "PrefsAdvanced|" msgid "Engine options" -msgstr "" +msgstr "Futtató motor beállításai" msgctxt "PrefsAdvanced|" msgid "Maximum # of engines: " -msgstr "" +msgstr "Futtató motorok maximális száma: " msgctxt "PrefsData|" msgid "Data Preferences" -msgstr "" +msgstr "Adat beállítások" msgctxt "PrefsData|" msgid "Synchronize automatically on data file save" -msgstr "" +msgstr "Automatikus szinkronizáció az adatfájl mentésekor" msgctxt "PrefsData|" msgid "Use default spreadsheet editor" -msgstr "" +msgstr "Alapértelmezett táblázatszerkesztő használata" msgctxt "PrefsData|" msgid "Select custom editor" -msgstr "" +msgstr "Egyedi szerkesztő kiválasztása" msgctxt "PrefsData|" msgid "Import threshold between Categorical or Scale" -msgstr "" +msgstr "Kategória és folyamatos változók közötti küszöbérték" msgctxt "PrefsData|" msgid "" @@ -828,14 +857,18 @@ msgid "" "'scale'.\n" "You need to reload your data to take effect! Check help for more info." msgstr "" +"Az egyedi értékek számára megadott küszöbérték, ami alatt egy váltóz még nem " +"számít folyamatos változónak.\n" +"Az adatokat újra kell tölteni, hogy ez a beállítása kifejtse a hatását. Több " +"információt a dokumentációban találsz." msgctxt "PrefsMissingValues|" msgid "Missing Value List" -msgstr "" +msgstr "Hiányzó értékek listája" msgctxt "PrefsMissingValues|" msgid "Remove missing value" -msgstr "" +msgstr "Hiányzó értékek eltávolítása" msgctxt "PrefsMissingValues|" msgid "Reset" @@ -843,7 +876,7 @@ msgstr "Visszaállítás" msgctxt "PrefsResults|" msgid "Results Preferences" -msgstr "" +msgstr "Eredmény beállítások" msgctxt "PrefsResults|" msgid "Table options" @@ -851,64 +884,69 @@ msgstr "Táblázatbeállítások" msgctxt "PrefsResults|" msgid "Display exact p-values" -msgstr "" +msgstr "Pontos p-értékek megjelenítése" msgctxt "PrefsResults|" msgid "Fix the number of decimals" -msgstr "" +msgstr "Helyiértékek számának rögzítése" msgctxt "PrefsResults|" msgid "Plot options" -msgstr "" +msgstr "Diagram beállítások" msgctxt "PrefsResults|" msgid "Use PPI of screen in plots: " -msgstr "" +msgstr "A képernyő PPI értékének használata a diagramokon: " msgctxt "PrefsResults|" msgid "Use the Pixels Per Inch of your screen to render your plots." msgstr "" +"A képernyőd Pixel Per Inch értékének használata a diagramok rajzolásához." msgctxt "PrefsResults|" msgid "Custom PPI: " -msgstr "" +msgstr "Egyedi PPI: " msgctxt "PrefsResults|" msgid "Image background color" -msgstr "" +msgstr "Kép háttérszín" msgctxt "PrefsResults|" msgid "White" -msgstr "" +msgstr "Fehér" msgctxt "PrefsResults|" msgid "" "This makes the background of all plots white, quite useful if you want to " "use it in LaTeX or submit it to a journal." msgstr "" +"Az összes diagram hátterét fehérre állítja, ami hasznos lehet, ha LaTeX " +"kódban akarod használni, vagy egy folyóiratnak beküldeni." msgctxt "PrefsResults|" msgid "Transparent" -msgstr "" +msgstr "Átlátszó" msgctxt "PrefsResults|" msgid "" "This makes the background of all plots transparent, quite useful if you want " "to use it seamlessly on any background that isn't white." msgstr "" +"Az összes diagram hátterét átlátszóra állítja, ami hasznos lehet, ha nem " +"fehér színű háttér előtt akarod használni." msgctxt "PrefsUI|" msgid "Fonts" -msgstr "" +msgstr "Betűtípusok" msgctxt "PrefsUI|" msgid "Interface:" -msgstr "" +msgstr "Interfész:" #, qt-format msgctxt "PrefsUI|" msgid "default: %1" -msgstr "" +msgstr "alapértelmezett: %1" msgctxt "PrefsUI|" msgid "Themes" @@ -917,36 +955,40 @@ msgstr "Témák" msgctxt "PrefsUI|" msgid "" "Switches to a light theme, this is the default and original flavour of JASP." -msgstr "" +msgstr "Világos téma használata, ez a JASP eredeti és alapértelmezett témája." msgctxt "PrefsUI|" msgid "" "Switches to a dark theme, makes JASP a lot easier on the eyes for those " "night owls out there." -msgstr "" +msgstr "Sötét téma használata, ez kímélőbb a szemnek." msgctxt "PrefsUI|" msgid "Miscellaneous options" -msgstr "" +msgstr "Egyéb beállítások" msgctxt "PrefsUI|" msgid "Zoom (%): " -msgstr "" +msgstr "Nagyítás (%): " msgctxt "PrefsUI|" msgid "" "Increase or decrease the size of the interface elements (text, buttons, etc)." msgstr "" +"A felhasználói felület elemeinek (szövegek, gombok, stb.) méretének " +"csökkentése vagy növelése." msgctxt "PrefsUI|" msgid "Scroll speed (pix/s): " -msgstr "" +msgstr "Görgetés sebessége (pix/s): " msgctxt "PrefsUI|" msgid "" "Set the speed with which you can scroll in the options, dataviewer and other " "places." msgstr "" +"A görgetés sebességének beállítása az adatok megjelenítésekor és egyéb " +"helyeken." msgctxt "PrefsUI|" msgid "" @@ -955,15 +997,24 @@ msgid "" "glitches, cannot see results or anything even) might fix them.\n" "Analyses will still be just as fast though." msgstr "" +"Egy \"biztonságosabb\" módú megjelenítésre vált (szoftveres rajzolásra).\n" +"Ennek hatására a megjelenítés lassab lesz, de ha furcsa problémákat " +"tapasztalsz (pl. villogó kép, nem látszanak az eredmények, ...), ez az opció " +"megoldhatja.\n" +"Az analízisek megjelenítése így is gyors lesz." msgctxt "PrefsUI|" msgid "" "Turns off all animations, this is implied when \"Safe Graphics Mode\" is on." msgstr "" +"Minden animációt kikapcsol, ez automatikusan bekapcsol, ha a \"Biztonságos " +"megjelenítő mód\" be van kapcsolva." msgctxt "PrefsUI|" msgid "Already disabled animations because \"Safe Graphics Mode\" is on" msgstr "" +"Az animációk már ki vannak kapcsolva, mert a \"Biztonságos megjelenítő mód\" " +"opció be van kapcsolva" msgctxt "PrefsUI|" msgid "" @@ -971,46 +1022,50 @@ msgid "" "made by Qt. This might solve some problems on Windows where JASP crashes on " "pressing \"Browse\"." msgstr "" +"Ha ki van kapcsolva, az operációs rendszer beépített párbeszédablakai " +"helyett a Qt-t használja majd. Ez megoldhat néhány problémát, amikor a JASP " +"összeomlik a \"Tallózás\" gombra kattintva." msgctxt "RecentFiles|" msgid "Recent Files" -msgstr "" +msgstr "Utoljára használt fájlok" msgctxt "ComputedColumnsConstructor|" msgid "Computed columns code clear(ed)" -msgstr "" +msgstr "Számított oszlopok kódja törölve" msgctxt "ComputedColumnsConstructor|" msgid "Computed columns code applied" -msgstr "" +msgstr "Számított oszlopok kódja mentve" msgctxt "ComputedColumnsConstructor|" msgid "Please enter all arguments - see fields marked in red." -msgstr "" +msgstr "Kérjük, minden paramétert adjon meg - lásd a pirossal jelölt mezőket." msgctxt "ComputedColumnsConstructor|" msgid "Only one formula per computed column allowed." -msgstr "" +msgstr "Egy számított oszlopban csak egy képletet használhatsz." msgctxt "ComputedColumnsConstructor|" msgid "Welcome to the drag and drop computed column constructor!" -msgstr "" +msgstr "Üdvözlünk a húzd-és-vidd számított oszlop szerkeszőben!" msgctxt "DropTrash|" msgid "Dump unwanted snippets here; double-click to erase the entire slate" -msgstr "" +msgstr "Húzd ide a nem kívánatos részleteket, dupla kattintással törölheted" msgctxt "FilterConstructor|" msgid "Filter cleared
    " -msgstr "" +msgstr "Szűrő törölve
    " msgctxt "FilterConstructor|" msgid "Filter applied
    " -msgstr "" +msgstr "Szűrő beállítva
    " msgctxt "FilterConstructor|" msgid "Please enter all arguments - see fields marked in red.
    " msgstr "" +"Kérjük, adjon meg minden paramétert - lásd a pirossal jelölt mezőket.
    " msgctxt "FilterConstructor|" msgid "" @@ -2208,6 +2263,8 @@ msgid "" "Unable to start the editor : %1. Please check your editor settings in the " "preference menu." msgstr "" +"A szerkesztőt nem sikerült elindítani: %1. Kérjük, ellenőrizze a szerkesztő " +"beállításait." #, qt-format msgctxt "MainWindow|" @@ -2215,19 +2272,21 @@ msgid "" "No default spreadsheet editor for file %1. Use Preferences to set the right " "editor." msgstr "" +"Nincs beállítva táblázatszerkesztő a %1 fájlhoz. Használja a beállítások " +"menüpontot a szerkesztő beállításához." msgctxt "MainWindow|" msgid "Remove All Analyses" -msgstr "" +msgstr "Minden analízis eltávolítása" msgctxt "MainWindow|" msgid "Do you really want to remove all analyses?" -msgstr "" +msgstr "Valóban el akar távolítani minden analízist?" #, qt-format msgctxt "RibbonModel|" msgid "Loading bundled module %1 failed" -msgstr "" +msgstr "A %1 csomagolt modul betöltése nem sikerült" #, qt-format msgctxt "RibbonModel|" @@ -2236,23 +2295,26 @@ msgid "" "\n" "%2" msgstr "" +"A %1 csomagolt modul betöltése nem sikerült az alábbi hibaüzenettel:\n" +"\n" +"%2" msgctxt "RibbonModel|" msgid "R (Beta)" -msgstr "" +msgstr "R (béta)" msgctxt "Modules::Upgrader|" msgid "Error Loading Upgrades" -msgstr "" +msgstr "Hiba történt a frissítések betöltése során" #, qt-format msgctxt "Modules::Upgrader|" msgid "While loading upgrades for %1 an error was encountered: %2" -msgstr "" +msgstr "Az alábbi hiba történt a %1 frissítéseinek betöltése során: %2" msgctxt "Modules::Upgrader|" msgid "Upgrades couldn't be read" -msgstr "" +msgstr "A frissítéseket nem sikerült beolvasni" msgctxt "Modules::Upgrader|" msgid "" @@ -2261,10 +2323,15 @@ msgid "" "might not be understood properly and some analyses might fail to load " "entirely." msgstr "" +"A régi JASP fájlok betöltéséhez szükséges frissítéseket nem sikerült " +"beolvasni.\n" +"Így is tudja használni a JASP-ot, és egyes régi fájlok betöltése is " +"sikerülhet, de néhány régi beállítást nem biztos, hogy sikerülni fog " +"beolvasni, és néhány analízis betöltése sem biztos, hogy sikerülni fog." msgctxt "OnlineDataManager|" msgid "File Changed" -msgstr "" +msgstr "Fájl megváltozott" msgctxt "OnlineDataManager|" msgid "" @@ -2272,22 +2339,25 @@ msgid "" "\n" "Would you like to override the online file?" msgstr "" +"A fájl egyetlen másolata megváltozott a megnyitása óta.\n" +"\n" +"Szeretné felülírni az online fájlt?" msgctxt "OnlineDataNodeOSF|" msgid "Initiating upload of " -msgstr "" +msgstr "Feltöltése indítása " msgctxt "OnlineDataNodeOSF|" msgid "Initiating download of " -msgstr "" +msgstr "Letöltése indítása " msgctxt "OnlineDataNodeOSF|" msgid "Initiating making new file " -msgstr "" +msgstr "Új fájl létrehozásának indítása " msgctxt "OnlineDataNodeOSF|" msgid "Initiating making new folder " -msgstr "" +msgstr "Új mappa létrehozásának indítása " msgctxt "OnlineDataNodeOSF|" msgid "Initiating osf action " @@ -2303,80 +2373,80 @@ msgstr "" msgctxt "OnlineDataNodeOSF|" msgid "Creating new file " -msgstr "" +msgstr "Új fájl létrehozása " msgctxt "OnlineDataNodeOSF|" msgid "Creating new folder " -msgstr "" +msgstr "Új mappa létrehozása " msgctxt "OnlineDataNodeOSF|" msgid "Osf action " -msgstr "" +msgstr "Osf művelet " #, qt-format msgctxt "OnlineDataNodeOSF|" msgid "%1 %2 failed because %3" -msgstr "" +msgstr "%1 %%2 nem sikerült, mert %3" msgctxt "OnlineDataNodeOSF|" msgid " in progress" -msgstr "" +msgstr " folyamatban" msgctxt "ResultMenuModel|" msgid "Collapse" -msgstr "" +msgstr "Becsuk" msgctxt "ResultMenuModel|" msgid "Edit Title" -msgstr "" +msgstr "Cím szerkesztése" msgctxt "ResultMenuModel|" msgid "Copy" -msgstr "" +msgstr "Másolás" msgctxt "ResultMenuModel|" msgid "Copy LaTeX" -msgstr "" +msgstr "LaTeX kód másoláa" msgctxt "ResultMenuModel|" msgid "Copy Citations" -msgstr "" +msgstr "Hivatkozások másolása" msgctxt "ResultMenuModel|" msgid "Save Image As" -msgstr "" +msgstr "Kép mentése másként" msgctxt "ResultMenuModel|" msgid "Edit Image" -msgstr "" +msgstr "Kép szerkesztése" msgctxt "ResultMenuModel|" msgid "Add Note" -msgstr "" +msgstr "Megjegyzés hozzáadása" msgctxt "ResultMenuModel|" msgid "Duplicate" -msgstr "" +msgstr "Duplikálás" msgctxt "ResultMenuModel|" msgid "Remove" -msgstr "" +msgstr "Eltávolítás" msgctxt "ResultMenuModel|" msgid "Remove All" -msgstr "" +msgstr "Az összes eltávolítása" msgctxt "ResultMenuModel|" msgid "Refresh All" -msgstr "" +msgstr "Az összes frissítése" msgctxt "ResultMenuModel|" msgid "Show Dependencies" -msgstr "" +msgstr "Függőségek megjelenítése" msgctxt "ResultMenuModel|" msgid "Export Results" -msgstr "" +msgstr "Eredmények exportálása" msgctxt "ResultsJsInterface|" msgid "Results Warning" @@ -2391,67 +2461,73 @@ msgid "" "\n" "Additional documentation will be available in future releases of JASP." msgstr "" +"Nemsokára érkezik!\n" +"========\n" +"\n" +"Jelenleg nem érhető el súgó ehhez az analízishez.\n" +"\n" +"A JASP későbbi kiadásaiban bővítjük a dokumentációt." msgctxt "QObject|" msgid "valid R code" -msgstr "" +msgstr "érvényes R kód" #, qt-format msgctxt "ComboBoxBase|" msgid "Unknown option %1 in DropDown %2" -msgstr "" +msgstr "Ismeretlen opció %1 a %2 legördülő menüben" msgctxt "ActionButtons|" msgid "Open" -msgstr "" +msgstr "Megnyitás" msgctxt "ActionButtons|" msgid "Save" -msgstr "" +msgstr "Mentés" msgctxt "ActionButtons|" msgid "Save As" -msgstr "" +msgstr "Mentés másként" msgctxt "ActionButtons|" msgid "Export Results" -msgstr "" +msgstr "Eredmények exportálása" msgctxt "ActionButtons|" msgid "Export Data" -msgstr "" +msgstr "Adatok exportálása" msgctxt "ActionButtons|" msgid "Sync Data" -msgstr "" +msgstr "Adatok szinkronizálása" msgctxt "ActionButtons|" msgid "Close" -msgstr "" +msgstr "Bezárás" msgctxt "ActionButtons|" msgid "Preferences" -msgstr "" +msgstr "Beállítások" msgctxt "ActionButtons|" msgid "About" -msgstr "" +msgstr "Névjegy" msgctxt "DataLibraryBreadCrumbsListModel|" msgid "Categories" -msgstr "" +msgstr "Kategóriák" msgctxt "FileMenu|" msgid "File Types" -msgstr "" +msgstr "Fájltípusok" msgctxt "FileMenu|" msgid "Failed to open file from OSF" -msgstr "" +msgstr "Nem sikerült az OSF fájl megnyitása" msgctxt "FileMenu|" msgid "No associated data file" -msgstr "" +msgstr "Nincs hozzárendelt adatfájl" msgctxt "FileMenu|" msgid "" @@ -2462,31 +2538,32 @@ msgstr "" msgctxt "FileMenu|" msgid "Find Data File" -msgstr "" +msgstr "Adatfájl keresése" msgctxt "FileMenu|" msgid "Data File" -msgstr "" +msgstr "Adatfájl" msgctxt "OSF|" msgid "Username and/or password are not correct. Please try again." -msgstr "" +msgstr "A felhasználónév vagy jelszó helytelen. Kérjük próbálja meg újra!" msgctxt "OSF|" msgid "OSF service not available. Please check your internet connection." msgstr "" +"Az OSF szolgáltatás nem elérhető. Kérjük ellenőrizze internet kapcsolatát!" msgctxt "OSF|" msgid "Connection Timeout error. Please check your internet connection." -msgstr "" +msgstr "Időtúllépési hiba. Kérjük ellenőrizze internet kapcsolatát!" msgctxt "OSF|" msgid "OSF Error" -msgstr "" +msgstr "OSF hiba" msgctxt "OSF|" msgid "Projects" -msgstr "" +msgstr "Projektek" msgctxt "OSF|" msgid "" @@ -2494,10 +2571,13 @@ msgid "" "\n" "To add a new project please use the online OSF services." msgstr "" +"Nem sikerült a fájlok hozzáadása a projektlistához.\n" +"\n" +"Új projektek az online OSF szolgáltatással adhat hozzá." msgctxt "OSF|" msgid "Data Providers" -msgstr "" +msgstr "Adatforrások" msgctxt "OSF|" msgid "" @@ -2510,25 +2590,27 @@ msgstr "" #, qt-format msgctxt "OSF|" msgid "Files cannot be added to '%1' for an unknown reason." -msgstr "" +msgstr "A fájlok hozzáadása a '%1'-hez nem sikerült ismeretlen hiba miatt." msgctxt "OSF|" msgid "File Types" -msgstr "" +msgstr "Fájltípusok" msgctxt "OSF|" msgid "Failed to open file from OSF" -msgstr "" +msgstr "Nem sikerült a fájl megnyitása az OSF-ből" msgctxt "OSF|" msgid "An error occured and the folder could not be created." -msgstr "" +msgstr "Hiba történt a mappa léterhozása közben." msgctxt "OSF|" msgid "" "A new folder cannot be added to the projects list.
    To add a new project " "please use the online OSF services." msgstr "" +"Nem sikerült a mappa hozzáadása a projektlistához.
    Új projekt " +"hozzáadásához az online OSF szolgáltatást használhatja." msgctxt "OSF|" msgid "" @@ -2543,60 +2625,60 @@ msgstr "" msgctxt "OSF|" msgid "Folder" -msgstr "" +msgstr "Mappa" msgctxt "OSF|" msgid "Login" -msgstr "" +msgstr "Belépés" msgctxt "OSF|" msgid "User or password cannot be empty." -msgstr "" +msgstr "A felhasználónév és a jelszó nem lehet üres." msgctxt "OSF|" msgid "Entry name cannot be empty." -msgstr "" +msgstr "A bejegyzés neve nem lehet üres." #, qt-format msgctxt "OSF|" msgid "%1 name can only contain the following characters A-Z a-z 0-9 _ %2" -msgstr "" +msgstr "%1 neve csak a következő karaktereket tartalmazhatja: A-Za-z0-9_%2" msgctxt "ResourceButtons|" msgid "Recent Files" -msgstr "" +msgstr "Nemrégiben megnyitott fájlok" msgctxt "ResourceButtons|" msgid "Current File" -msgstr "" +msgstr "Jelenlegi fájl" msgctxt "ResourceButtons|" msgid "Computer" -msgstr "" +msgstr "Számítógép" msgctxt "ResourceButtons|" msgid "OSF" -msgstr "" +msgstr "OSF" msgctxt "ResourceButtons|" msgid "Data Library" -msgstr "" +msgstr "Adatkönyvtár" msgctxt "ResourceButtons|" msgid "Data" -msgstr "" +msgstr "Adat" msgctxt "ResourceButtons|" msgid "Results" -msgstr "" +msgstr "Eredmények" msgctxt "ResourceButtons|" msgid "Interface" -msgstr "" +msgstr "Felhasználói felület" msgctxt "ResourceButtons|" msgid "Advanced" -msgstr "" +msgstr "Haladó" #, qt-format msgctxt "ListModelCustomContrasts|" @@ -2606,7 +2688,7 @@ msgstr "" #, qt-format msgctxt "ListModelLayersAssigned|" msgid "Layer %1" -msgstr "" +msgstr "Réteg %1" #, qt-format msgctxt "RadioButtonsGroupBase|" @@ -2636,31 +2718,31 @@ msgstr "" msgctxt "SortMenuModel|" msgid "Sort by name" -msgstr "" +msgstr "Rendezés név szerint" msgctxt "SortMenuModel|" msgid "Sort by name A-Z" -msgstr "" +msgstr "Rendezés név szerint A-Z" msgctxt "SortMenuModel|" msgid "Sort by name Z-A" -msgstr "" +msgstr "Rendezés név szerint Z-A" msgctxt "SortMenuModel|" msgid "Sort by type" -msgstr "" +msgstr "Rendezés típus szerint" msgctxt "SortMenuModel|" msgid "Sort by date" -msgstr "" +msgstr "Rendezés dátum szerint" msgctxt "SortMenuModel|" msgid "Sort by size" -msgstr "" +msgstr "Rendezés méret szerint" msgctxt "SortMenuModel|" msgid "SortMenuModel not called with a sortable parent" -msgstr "" +msgstr "SortMenuModel nem rendezhető szűlővel meghívva" msgctxt "TextAreaBase|" msgid "Model applied" @@ -2668,52 +2750,52 @@ msgstr "" msgctxt "TextInputBase|" msgid "The expression did not return a number." -msgstr "" +msgstr "A kifejezés nem számott adott vissza." msgctxt "TextInputBase|" msgid "Integer Field" -msgstr "" +msgstr "Egész szám mező" msgctxt "TextInputBase|" msgid "Number Field" -msgstr "" +msgstr "Szám mező" msgctxt "TextInputBase|" msgid "Percentage Field" -msgstr "" +msgstr "Százalék mező" msgctxt "TextInputBase|" msgid "Integers Field" -msgstr "" +msgstr "Egész számok mező" msgctxt "TextInputBase|" msgid "Doubles Field" -msgstr "" +msgstr "Lebegőpontos számok mező" msgctxt "TextInputBase|" msgid "Add Column Field" -msgstr "" +msgstr "Oszlop hozzáadása mező" msgctxt "TextInputBase|" msgid "Add Computed Column Field" -msgstr "" +msgstr "Számított oszlop hozzáadása mező" msgctxt "TextInputBase|" msgid "Formula Field" -msgstr "" +msgstr "Képlet mező" msgctxt "TextInputBase|" msgid "Formulas Field" -msgstr "" +msgstr "Képletek mező" msgctxt "TextInputBase|" msgid "Text Field" -msgstr "" +msgstr "Szöveg mező" #, qt-format msgctxt "TextInputBase|" msgid "The value (%1) must be %2" -msgstr "" +msgstr "A %1 értéke %2 kell, hogy legyen" #, qt-format msgctxt "VariablesListBase|" @@ -2762,14 +2844,15 @@ msgstr "" msgctxt "ComputeColumnWindow|" msgid "returns true if string contains substring at least once" msgstr "" +"igazat vissza, ha a szöveg legalább egyszer tartalmazza a keresett szöveget" msgctxt "FactorsForm|" msgid "+" -msgstr "" +msgstr "+" msgctxt "FactorsForm|" msgid "-" -msgstr "" +msgstr "-" msgctxt "FilterWindow|" msgid "Standardizes the variable" @@ -2778,10 +2861,11 @@ msgstr "" msgctxt "FilterWindow|" msgid "returns true if string contains substring at least once" msgstr "" +"igazat vissza, ha a szöveg legalább egyszer tartalmazza a keresett szöveget" msgctxt "PlotEditingAxis|" msgid "Title" -msgstr "" +msgstr "Cím" msgctxt "PlotEditingAxis|" msgid "Specify sequence" @@ -2813,23 +2897,25 @@ msgstr "" msgctxt "PlotEditingAxis|" msgid "Lower limit" -msgstr "" +msgstr "Alsó határérték" msgctxt "PlotEditingAxis|" msgid "Upper limit" -msgstr "" +msgstr "Felső határérték" msgctxt "PlotEditor|" msgid "x-axis" -msgstr "" +msgstr "x-tengely" msgctxt "PlotEditor|" msgid "y-axis" -msgstr "" +msgstr "y-tengely" msgctxt "VariablesWindow|" msgid "Edit the labels here or choose which values should be filtered out." msgstr "" +"Itt szerkesztheti a címkéket, vagy kiválaszthatja, hogy melyik értékeket " +"kell kiszűrni." msgctxt "DataSetPackage|" msgid "Something went wrong converting columntype, but it is unclear what." @@ -2849,11 +2935,11 @@ msgstr "" msgctxt "LabelModel|" msgid "Value" -msgstr "" +msgstr "Érték" msgctxt "LabelModel|" msgid "Label" -msgstr "" +msgstr "Címke" #, qt-format msgctxt "EngineRepresentation|" @@ -2946,7 +3032,7 @@ msgstr "" msgctxt "Modules::DynamicModules|" msgid "Select a folder" -msgstr "" +msgstr "Mappa kiválasztása" msgctxt "Modules::DynamicModules|" msgid "" @@ -2966,7 +3052,7 @@ msgstr "" msgctxt "Modules::DynamicModules|" msgid "Missing files or folders" -msgstr "" +msgstr "Hiányzó mappák vagy fájlok" msgctxt "Modules::DynamicModules|" msgid "" @@ -2980,7 +3066,7 @@ msgstr "" msgctxt "Modules::DynamicModules|" msgid "Create a R directory containing your analysis code." -msgstr "" +msgstr "R mappa létrehozása az analízis kódjával." msgctxt "Modules::DynamicModules|" msgid "Create a inst/qml directory containing your optionsforms." @@ -2994,7 +3080,7 @@ msgstr "" #, qt-format msgctxt "Modules::DynamicModules|" msgid "Missing %1" -msgstr "" +msgstr "%1 hiányzik" #, qt-format msgctxt "Modules::DynamicModules|" @@ -3016,7 +3102,7 @@ msgstr "" #, qt-format msgctxt "Modules::DynamicModules|" msgid "%1 was removed!" -msgstr "" +msgstr "%1 eltávolítva!" #, qt-format msgctxt "Modules::DynamicModules|" @@ -3028,7 +3114,7 @@ msgstr "" #, qt-format msgctxt "Modules::DynamicModules|" msgid "Missing folder %1" -msgstr "" +msgstr "Hiányzó mappa: %1" #, qt-format msgctxt "Modules::DynamicModules|" @@ -3113,27 +3199,27 @@ msgstr "" msgctxt "FactorLevelList|" msgid "Factor" -msgstr "" +msgstr "Tényező" msgctxt "FactorLevelList|" msgid "Level" -msgstr "" +msgstr "Szint" msgctxt "FactorLevelList|" msgid "New Factor" -msgstr "" +msgstr "Új tényező" msgctxt "FactorLevelList|" msgid "New Level" -msgstr "" +msgstr "Új szint" msgctxt "PrefsAdvanced|" msgid "Remember enabled modules" -msgstr "" +msgstr "Engedélyezett modulok megjegyzése" msgctxt "PrefsAdvanced|" msgid "Use default PAT for Github" -msgstr "" +msgstr "Alapértelmezett Github token (PAT) használata" msgctxt "PrefsAdvanced|" msgid "" @@ -3143,7 +3229,7 @@ msgstr "" msgctxt "PrefsAdvanced|" msgid "Private GITHUB_PAT:" -msgstr "" +msgstr "Saját GitHub token:" msgctxt "PrefsAdvanced|" msgid "Let JASP guess the best setting for LC_CTYPE (recommended!)" @@ -3167,31 +3253,31 @@ msgstr "" msgctxt "PrefsUI|" msgid "Light theme" -msgstr "" +msgstr "Világos téma" msgctxt "PrefsUI|" msgid "Dark theme" -msgstr "" +msgstr "Sötét téma" msgctxt "PrefsUI|" msgid "Preferred language" -msgstr "" +msgstr "Preferált nyelv" msgctxt "PrefsUI|" msgid "Choose language " -msgstr "" +msgstr "Nyelv kiválasztása " msgctxt "PrefsUI|" msgid "Safe graphics mode" -msgstr "" +msgstr "Biztonságos megjelenítés mód" msgctxt "PrefsUI|" msgid "Disable animations" -msgstr "" +msgstr "Animációk kikapcsolása" msgctxt "PrefsUI|" msgid "Use native file dialogs" -msgstr "" +msgstr "Natív párbeszédablakok használata" msgctxt "ModulesMenu|" msgid "Select a developer module by clicking here" @@ -3199,7 +3285,7 @@ msgstr "" msgctxt "RibbonBar|" msgid "Show main menu" -msgstr "" +msgstr "Főmenü megjelenítése" msgctxt "RibbonBar|" msgid "Show modules menu" @@ -3231,11 +3317,11 @@ msgstr "" msgctxt "jasp-qml-style-example|" msgid "Variables" -msgstr "" +msgstr "Változók" msgctxt "jasp-qml-style-example|" msgid "Split" -msgstr "" +msgstr "Szétválasztás" msgctxt "KnownIssues|" msgid "" @@ -3272,7 +3358,7 @@ msgstr "" msgctxt "MainWindow|" msgid "Cancel" -msgstr "" +msgstr "Mégse" msgctxt "Modules::DynamicModules|" msgid "" @@ -3308,7 +3394,7 @@ msgstr "" msgctxt "RibbonModel|" msgid "Execute R code in a console" -msgstr "" +msgstr "R kód futtatása a konzolban" msgctxt "TableView|" msgid "Add to the left" @@ -3362,7 +3448,7 @@ msgstr "" msgctxt "PlotEditingAxis|" msgid "Label" -msgstr "" +msgstr "Címke" msgctxt "PlotEditingAxis|" msgid "Tick #" @@ -3394,7 +3480,7 @@ msgstr "" msgctxt "MainWindow|" msgid "Clean" -msgstr "" +msgstr "Törlés" msgctxt "PrefsData|" msgid "On Linux the default spreadsheet editor is always used." @@ -3402,23 +3488,23 @@ msgstr "" msgctxt "PlotEditor|" msgid "OK" -msgstr "" +msgstr "OK" msgctxt "PlotEditor|" msgid "Cancel" -msgstr "" +msgstr "Mégse" msgctxt "PlotEditor|" msgid "Reset defaults" -msgstr "" +msgstr "Alapbeállítások visszaállítása" msgctxt "PlotEditingAxis|" msgid "Show title" -msgstr "" +msgstr "Cím megjelenítése" msgctxt "PlotEditingAxis|" msgid "Show axis" -msgstr "" +msgstr "Tengely megjelenítése" msgctxt "PlotEditingAxis|" msgid "Ticks:" @@ -3426,11 +3512,11 @@ msgstr "" msgctxt "PlotEditingAxis|" msgid "Position" -msgstr "" +msgstr "Pozíció" msgctxt "PlotEditingAxis|" msgid "Advanced" -msgstr "" +msgstr "Haladó" msgctxt "PlotEditingAxis|" msgid "Parse title as R expression" @@ -3442,7 +3528,7 @@ msgstr "" msgctxt "PlotEditor|" msgid "Save image as" -msgstr "" +msgstr "Kép mentése másként" #, qt-format msgctxt "EngineRepresentation|" @@ -3475,7 +3561,7 @@ msgstr "" msgctxt "PlotEditor|" msgid "Open Documentation" -msgstr "" +msgstr "Dokumentáció megnyitása" msgctxt "AboutWindow|" msgid "Open Source Components" diff --git a/Desktop/po/jaspDesktop-id.po b/Desktop/po/jaspDesktop-id.po index bb494e5930..da31d0100c 100644 --- a/Desktop/po/jaspDesktop-id.po +++ b/Desktop/po/jaspDesktop-id.po @@ -5119,3 +5119,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-ja.po b/Desktop/po/jaspDesktop-ja.po index d7b5a407e6..a902c8f18e 100644 --- a/Desktop/po/jaspDesktop-ja.po +++ b/Desktop/po/jaspDesktop-ja.po @@ -5407,3 +5407,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-nl.po b/Desktop/po/jaspDesktop-nl.po index 42a85a3e4e..7d132f7e99 100644 --- a/Desktop/po/jaspDesktop-nl.po +++ b/Desktop/po/jaspDesktop-nl.po @@ -5431,3 +5431,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-pl.po b/Desktop/po/jaspDesktop-pl.po index d629437d7a..1b20fe7fbe 100644 --- a/Desktop/po/jaspDesktop-pl.po +++ b/Desktop/po/jaspDesktop-pl.po @@ -5440,3 +5440,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-pt.po b/Desktop/po/jaspDesktop-pt.po index cd860cd44d..55ee336313 100644 --- a/Desktop/po/jaspDesktop-pt.po +++ b/Desktop/po/jaspDesktop-pt.po @@ -5346,3 +5346,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-pt_BR.po b/Desktop/po/jaspDesktop-pt_BR.po index 4d28a9423c..d51418d3b0 100644 --- a/Desktop/po/jaspDesktop-pt_BR.po +++ b/Desktop/po/jaspDesktop-pt_BR.po @@ -5346,3 +5346,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-ru.po b/Desktop/po/jaspDesktop-ru.po index f0b5a6072d..d85ec82106 100644 --- a/Desktop/po/jaspDesktop-ru.po +++ b/Desktop/po/jaspDesktop-ru.po @@ -5390,3 +5390,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-tr.po b/Desktop/po/jaspDesktop-tr.po index 2e5278b48a..b8a948377c 100644 --- a/Desktop/po/jaspDesktop-tr.po +++ b/Desktop/po/jaspDesktop-tr.po @@ -29,7 +29,7 @@ msgstr "Kaydedilecek dosyayı seçin" msgctxt "FileSelector|" msgid "Select file to load" -msgstr "" +msgstr "Yüklemek için dosya seçiniz" msgctxt "FileSelector|" msgid "Browse" @@ -5064,3 +5064,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop-zh_Hans.po b/Desktop/po/jaspDesktop-zh_Hans.po index 281922f7c9..e34a71bbad 100644 --- a/Desktop/po/jaspDesktop-zh_Hans.po +++ b/Desktop/po/jaspDesktop-zh_Hans.po @@ -5235,11 +5235,11 @@ msgstr "未知" msgctxt "ColumnBasicInfo|" msgid "" -msgstr "" +msgstr "<首先填写列名称>" msgctxt "PrefsData|" msgid "Maximum allowed levels for scale when used as nominal/ordinal" -msgstr "" +msgstr "当连续型变量被用作名义/有序类型时允许的最大水平" msgctxt "PrefsData|" msgid "" @@ -5247,11 +5247,13 @@ msgid "" "scale variable is used, JASP checks whether the number of levels of this " "variable exceeds this maximum." msgstr "" +"对于某些变量仅接受名义或有序的分析,如果使用了连续变量,JASP 会检查该变量的水" +"平数是否超出此最大值。" #, qt-format msgctxt "VariablesListBase|" msgid "Maximum number of levels is %1. Variable %2 has %3 levels." -msgstr "" +msgstr "最大水平数仅允许 %1。变量 %2 有 %3 个水平。" #, qt-format msgctxt "VariablesListBase|" @@ -5261,10 +5263,63 @@ msgid "" "either change its type, or change 'Maximum allowed levels for scale' in " "Preferences / Data menu" msgstr "" +"尝试将连续变量 %1 转换为 %2 变量,但其水平数 %3 超出最大值 %4。如果您仍想使用" +"此变量,请更改其度量类型,或在“首选项/数据”菜单中更改“连续变量允许的最大水平”" #, qt-format msgctxt "VariablesListBase|" msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" +msgstr "数值的最小数量为 %1。变量 %2 仅有 %3 个不同的数值" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "正在加载新的数据集" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "新建" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "正在导入 Excel 文件" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "所有数据集 %1" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "JASP 文件 %1" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "CSV 文本文件 %1" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "电子表格文件 %1" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "SPSS 文件 %1" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "Stata 文件 %1" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "SAS 文件 %1" + +msgctxt "ColorPalette|" +msgid "JASP" msgstr "" diff --git a/Desktop/po/jaspDesktop-zh_Hant.po b/Desktop/po/jaspDesktop-zh_Hant.po index 84c6ff2602..4d35b29680 100644 --- a/Desktop/po/jaspDesktop-zh_Hant.po +++ b/Desktop/po/jaspDesktop-zh_Hant.po @@ -5206,3 +5206,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/po/jaspDesktop.pot b/Desktop/po/jaspDesktop.pot index c67886a932..46bc591ee7 100644 --- a/Desktop/po/jaspDesktop.pot +++ b/Desktop/po/jaspDesktop.pot @@ -5020,3 +5020,54 @@ msgid "" "Minimum number of numeric values is %1. Variable %2 has only %3 different " "numeric values" msgstr "" + +msgctxt "AsyncLoader|" +msgid "Loading New Data Set" +msgstr "" + +msgctxt "ActionButtons|" +msgid "New" +msgstr "" + +msgctxt "FileEvent|" +msgid "Importing Excel File" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "All Data Sets %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "JASP Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "CSV Text Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Spreadsheet Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SPSS Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "Stata Files %1" +msgstr "" + +#, qt-format +msgctxt "Computer|" +msgid "SAS Files %1" +msgstr "" + +msgctxt "ColorPalette|" +msgid "JASP" +msgstr "" diff --git a/Desktop/resources/CC-Attributions.txt b/Desktop/resources/CC-Attributions.txt index c294689336..b3f17c0d48 100644 --- a/Desktop/resources/CC-Attributions.txt +++ b/Desktop/resources/CC-Attributions.txt @@ -1,8 +1,8 @@ Creative Commons requires us to give proper courtesy to the creators of certain files. - columnConstructorBackground.png: Originally from "Timur Zima, from the Noun Project" filter.png, filterConstructorBackground.png, exclamation.svg, font.svg, eyeOpen.png, eyeClosed.png, triangle-exclamation round-information(modified): - - originally from "Font Awesome by Dave Gandy - https://fortawesome.github.com/Font-Awesome" +originally from "Font Awesome by Dave Gandy - https://fortawesome.github.com/Font-Awesome" + +sqrtSelector.png vaguely based on https://www.flaticon.com/free-icon/square-root-mathematical-symbol_43743 by Freepik \ No newline at end of file diff --git a/Desktop/resources/icons/darkTheme/divide.png b/Desktop/resources/icons/darkTheme/divide.png index f35ecd649a..43b6ec68a7 100644 Binary files a/Desktop/resources/icons/darkTheme/divide.png and b/Desktop/resources/icons/darkTheme/divide.png differ diff --git a/Desktop/resources/icons/darkTheme/minus.png b/Desktop/resources/icons/darkTheme/minus.png new file mode 100644 index 0000000000..bfb24647ae Binary files /dev/null and b/Desktop/resources/icons/darkTheme/minus.png differ diff --git a/Desktop/resources/icons/darkTheme/modulo.png b/Desktop/resources/icons/darkTheme/modulo.png index a7131a08dd..6425066516 100644 Binary files a/Desktop/resources/icons/darkTheme/modulo.png and b/Desktop/resources/icons/darkTheme/modulo.png differ diff --git a/Desktop/resources/icons/darkTheme/multiply.png b/Desktop/resources/icons/darkTheme/multiply.png new file mode 100644 index 0000000000..bb080d532b Binary files /dev/null and b/Desktop/resources/icons/darkTheme/multiply.png differ diff --git a/Desktop/resources/icons/darkTheme/plus.png b/Desktop/resources/icons/darkTheme/plus.png new file mode 100644 index 0000000000..bb7736a687 Binary files /dev/null and b/Desktop/resources/icons/darkTheme/plus.png differ diff --git a/Desktop/resources/icons/darkTheme/sqrtSelector.png b/Desktop/resources/icons/darkTheme/sqrtSelector.png new file mode 100644 index 0000000000..0ef33d6859 Binary files /dev/null and b/Desktop/resources/icons/darkTheme/sqrtSelector.png differ diff --git a/Desktop/resources/icons/lightTheme/minus.png b/Desktop/resources/icons/lightTheme/minus.png new file mode 100644 index 0000000000..62b4374b12 Binary files /dev/null and b/Desktop/resources/icons/lightTheme/minus.png differ diff --git a/Desktop/resources/icons/lightTheme/modulo.png b/Desktop/resources/icons/lightTheme/modulo.png index 2ae405892c..86e676640e 100644 Binary files a/Desktop/resources/icons/lightTheme/modulo.png and b/Desktop/resources/icons/lightTheme/modulo.png differ diff --git a/Desktop/resources/icons/lightTheme/multiply.png b/Desktop/resources/icons/lightTheme/multiply.png new file mode 100644 index 0000000000..39d42d0e86 Binary files /dev/null and b/Desktop/resources/icons/lightTheme/multiply.png differ diff --git a/Desktop/resources/icons/lightTheme/plus.png b/Desktop/resources/icons/lightTheme/plus.png new file mode 100644 index 0000000000..91c04cb043 Binary files /dev/null and b/Desktop/resources/icons/lightTheme/plus.png differ diff --git a/Desktop/resources/icons/lightTheme/sqrtSelector.png b/Desktop/resources/icons/lightTheme/sqrtSelector.png new file mode 100644 index 0000000000..431809b579 Binary files /dev/null and b/Desktop/resources/icons/lightTheme/sqrtSelector.png differ diff --git a/Desktop/utilities/application.cpp b/Desktop/utilities/application.cpp index d83da04d65..39cc3b1da4 100644 --- a/Desktop/utilities/application.cpp +++ b/Desktop/utilities/application.cpp @@ -25,7 +25,7 @@ #include "utilities/settings.h" #include -void Application::init(QString filePath, bool unitTest, int timeOut, bool save, bool logToFile, const Json::Value & dbJson, QString reportingPath) +void Application::init(QString filePath, bool newData, bool unitTest, int timeOut, bool save, bool logToFile, const Json::Value & dbJson, QString reportingPath) { std::cout << "Application init entered" << std::endl; @@ -36,14 +36,24 @@ void Application::init(QString filePath, bool unitTest, int timeOut, bool save, _mainWindow = new MainWindow(this); - if(unitTest) - _mainWindow->testLoadedJaspFile(timeOut, save); + connect(_mainWindow, &MainWindow::qmlLoadedChanged, _mainWindow, [&, newData, unitTest, filePath, dbJson]() { + // The QML files are not yet laoded when MainWindow is just created (loadQML is called via a QTmer::singleShot) + // But to correctly work, the following calls need the QML files to be loaded. + if (newData) + _mainWindow->showNewData(); + else + { + if(unitTest) + _mainWindow->testLoadedJaspFile(timeOut, save); - if(filePath.size() > 0) - _mainWindow->open(filePath); - - if(!dbJson.isNull()) - _mainWindow->open(dbJson); + if(filePath.size() > 0) + _mainWindow->open(filePath); + + if(!dbJson.isNull()) + _mainWindow->open(dbJson); + } + + }); if(reportingPath != "") _mainWindow->reportHere(reportingPath); diff --git a/Desktop/utilities/application.h b/Desktop/utilities/application.h index d8585440b9..3fd8f52d41 100644 --- a/Desktop/utilities/application.h +++ b/Desktop/utilities/application.h @@ -34,7 +34,7 @@ class Application : public QApplication virtual bool notify(QObject *receiver, QEvent *event) OVERRIDE; virtual bool event(QEvent *event) OVERRIDE; - void init(QString filePath, bool unitTest, int timeOut, bool save, bool logToFile, const Json::Value & dbJson, QString reportingPath); + void init(QString filePath, bool newData, bool unitTest, int timeOut, bool save, bool logToFile, const Json::Value & dbJson, QString reportingPath); signals: diff --git a/Desktop/utilities/processhelper.cpp b/Desktop/utilities/processhelper.cpp index 016fd0ac9f..b0b4c91097 100644 --- a/Desktop/utilities/processhelper.cpp +++ b/Desktop/utilities/processhelper.cpp @@ -1,12 +1,9 @@ #include "processhelper.h" #include "utilities/appdirs.h" - -#ifdef _WIN32 #include "utilities/qutils.h" #include "log.h" -#endif -QProcessEnvironment ProcessHelper::getProcessEnvironmentForJaspEngine() +QProcessEnvironment ProcessHelper::getProcessEnvironmentForJaspEngine(bool bootStrap) { QDir programDir = AppDirs::programDir(); QString engineExe = programDir.absoluteFilePath("JASPEngine"); @@ -21,8 +18,8 @@ QProcessEnvironment ProcessHelper::getProcessEnvironmentForJaspEngine() //Seems a bit weird but we need to tell this to jaspBase so it can tell renv to run it again because that will be running in a subprocess. //Which also means we have the following process -> subprocess structure while installing a dynamic module: // jasp -> JASPEngine with R-embedded -> Separate R -> separate instances of JASPEngine... - env.insert("JASPENGINE_LOCATION", engineExe); - + env.insert("JASPENGINE_LOCATION", engineExe); + QString TZDIR = AppDirs::rHome() + "/share/zoneinfo"; QString rHomePath = AppDirs::rHome(); QDir rHome ( rHomePath ); @@ -45,7 +42,7 @@ QProcessEnvironment ProcessHelper::getProcessEnvironmentForJaspEngine() R_HOME = shortenWinPaths(rHome.absolutePath()), JAGS_HOME = shortenWinPaths(programDir.absoluteFilePath("R/opt/jags/")); // JAGS_LIBDIR = shortenWinPaths(programDir.absoluteFilePath("R/opt/jags/lib/")); - + Log::log() << "R_HOME set to " << R_HOME << std::endl; env.insert("PATH", PATH); @@ -55,7 +52,10 @@ QProcessEnvironment ProcessHelper::getProcessEnvironmentForJaspEngine() #undef ARCH_SUBPATH - env.insert("R_LIBS", R_HOME + "/library"); + if(bootStrap) + env.insert("R_LIBS", programDir.absoluteFilePath("Modules/Tools/junction_bootstrap_library") + ";" + R_HOME + "/library"); + else + env.insert("R_LIBS", AppDirs::bundledModulesDir() + "Tools/R_cpp_includes_library" + ";" + R_HOME + "/library"); env.insert("R_ENVIRON", "something-which-doesn't-exist"); env.insert("R_PROFILE", "something-which-doesn't-exist"); @@ -73,7 +73,7 @@ QProcessEnvironment ProcessHelper::getProcessEnvironmentForJaspEngine() env.insert("R_HOME", rHome.absolutePath()); env.insert("RHOME", rHome.absolutePath()); //For Rscript env.insert("JASP_R_HOME", rHome.absolutePath()); //Used by the modified R script in jasp-required-files/Framework/etc/bin to make sure we use the actual R of JASP! (https://github.com/jasp-stats/INTERNAL-jasp/issues/452) - env.insert("R_LIBS", rHome.absoluteFilePath("library") + ":" + programDir.absoluteFilePath("R/library")); + env.insert("R_LIBS", programDir.absoluteFilePath("../Modules/Tools/R_cpp_includes_library") + ":" + rHome.absoluteFilePath("library") + ":" + programDir.absoluteFilePath("R/library") + custom_R_library); env.insert("JAGS_HOME", rHome.absolutePath() + "/opt/jags/lib/JAGS/"); // env.insert("JAGS_LIBDIR", rHome.absolutePath() + "/opt/jags/lib/"); @@ -84,11 +84,13 @@ QProcessEnvironment ProcessHelper::getProcessEnvironmentForJaspEngine() env.insert("LC_CTYPE", "UTF-8"); //This isn't really a locale but seems necessary to get proper output from gettext on mac env.insert("TZDIR", TZDIR); - +#elif FLATPAK_USED + env.insert("R_HOME", rHome.absolutePath()); + env.insert("R_LIBS", "/app/Modules/Tools/R_cpp_includes_library:/app/lib64/R/library" + custom_R_library); + env.insert("LD_LIBRARY_PATH", "/app/Modules/Tools/R_cpp_includes_library/RInside/lib/:/app/lib64/R/lib/"); #else // linux - env.insert("LD_LIBRARY_PATH", rHome.absoluteFilePath("lib") + ":" + rHome.absoluteFilePath("library/RInside/lib") + ":" + rHome.absoluteFilePath("library/Rcpp/lib") + ":" + rHome.absoluteFilePath("site-library/RInside/lib") + ":" + rHome.absoluteFilePath("site-library/Rcpp/lib") + ":/app/lib/:/app/lib64/"); env.insert("R_HOME", rHome.absolutePath()); - env.insert("R_LIBS", programDir.absoluteFilePath("R/library") + custom_R_library + ":" + rHome.absoluteFilePath("library") + ":" + rHome.absoluteFilePath("site-library")); + env.insert("R_LIBS", programDir.absoluteFilePath("../Modules/Tools/R_cpp_includes_library") + ":" + programDir.absoluteFilePath("R/library") + custom_R_library); #endif env.insert("R_LIBS_SITE", ""); @@ -99,5 +101,10 @@ QProcessEnvironment ProcessHelper::getProcessEnvironmentForJaspEngine() env.insert("R_LIBS_USER", (AppDirs::programDir().absolutePath().toStdString() + "/../R/library").c_str()); #endif + Log::log() << "R_LIBS:" << env.value("R_LIBS") << "\n" << + "R_LIBS_USER:" << env.value("R_LIBS_USER") << "\n" << + "LD_LIBRARY_PATH:" << env.value("LD_LIBRARY_PATH") << "\n" << + std::endl; + return(env); } diff --git a/Desktop/utilities/processhelper.h b/Desktop/utilities/processhelper.h index b0e9d85608..db671242b4 100644 --- a/Desktop/utilities/processhelper.h +++ b/Desktop/utilities/processhelper.h @@ -10,7 +10,7 @@ class ProcessHelper { public: - static QProcessEnvironment getProcessEnvironmentForJaspEngine(); + static QProcessEnvironment getProcessEnvironmentForJaspEngine(bool bootStrap = false); private: ProcessHelper(){} diff --git a/Desktop/widgets/filemenu/actionbuttons.cpp b/Desktop/widgets/filemenu/actionbuttons.cpp index 889aa9f8ec..5f358f3a85 100644 --- a/Desktop/widgets/filemenu/actionbuttons.cpp +++ b/Desktop/widgets/filemenu/actionbuttons.cpp @@ -22,6 +22,7 @@ void ActionButtons::loadButtonData() _data = { + {FileOperation::New, tr("New"), true, {} }, {FileOperation::Open, tr("Open"), true, {ResourceButtons::Computer, ResourceButtons::OSF, ResourceButtons::Database, ResourceButtons::RecentFiles, ResourceButtons::DataLibrary } }, {FileOperation::Save, tr("Save"), false, {} }, {FileOperation::SaveAs, tr("Save As"), false, {ResourceButtons::Computer, ResourceButtons::OSF } }, diff --git a/Desktop/widgets/filemenu/actionbuttons.h b/Desktop/widgets/filemenu/actionbuttons.h index ec3dc12809..ed0cb2fc56 100644 --- a/Desktop/widgets/filemenu/actionbuttons.h +++ b/Desktop/widgets/filemenu/actionbuttons.h @@ -13,7 +13,7 @@ class ActionButtons : public QAbstractListModel Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged ) public: - enum FileOperation {None = 0, Open, Save, SaveAs, ExportResults, ExportData, SyncData, Close, Preferences, Contact, Community, About}; + enum FileOperation {None = 0, New, Open, Save, SaveAs, ExportResults, ExportData, SyncData, Close, Preferences, Contact, Community, About}; Q_ENUM(FileOperation) struct DataRow { FileOperation operation; QString name; bool enabled; std::set resourceButtons; }; diff --git a/Desktop/widgets/filemenu/computer.cpp b/Desktop/widgets/filemenu/computer.cpp index 247c92b4ec..58314facb6 100644 --- a/Desktop/widgets/filemenu/computer.cpp +++ b/Desktop/widgets/filemenu/computer.cpp @@ -39,9 +39,16 @@ FileEvent *Computer::browseOpen(const QString &path) else browsePath = path; - QString filter = "Data Sets (*.jasp *.csv *.txt *.tsv *.sav *.zsav *.ods *.dta *.por *.sas7bdat *.sas7bcat *.xpt)"; + QString filter = tr("All Data Sets %1").arg("(*.jasp *.csv *.txt *.tsv *.sav *.zsav *.ods *.xls *.xlsx *.dta *.por *.sas7bdat *.sas7bcat *.xpt);;") + + tr("JASP Files %1").arg("(*.jasp);;") + + tr("CSV Text Files %1").arg("(*.csv *.txt *.tsv);;") + + tr("Spreadsheet Files %1").arg("(*.ods *.xls *.xlsx);;") + + tr("SPSS Files %1").arg("(*.sav *.zsav *.por)") + ";;" + + tr("Stata Files %1").arg("(*.dta);;") + + tr("SAS Files %1").arg("(*.sas7bdat *.sas7bcat *.xpt)"); + if (mode() == FileEvent::FileSyncData) - filter = "Data Sets (*.csv *.txt *.tsv *.sav *.ods)"; + filter = "Data Sets (*.csv *.txt *.tsv *.sav *.ods *.xls *.xlsx)"; Log::log() << "Now calling MessageForwarder::browseOpenFile(\"Open\", \"" << browsePath.toStdString() << "\", \"" << filter.toStdString() << "\")" << std::endl; QString finalPath = MessageForwarder::browseOpenFile("Open", browsePath, filter); @@ -89,7 +96,7 @@ FileEvent *Computer::browseSave(const QString &path, FileEvent::FileMode mode) case FileEvent::FileSyncData: caption = tr("Sync Data"); - filter = tr("Data Files") += " (*.csv *.txt *.tsv *.sav *.ods)"; + filter = tr("Data Files") += " (*.csv *.txt *.tsv *.sav *.ods *.xls *.xlsx)"; browsePath += ".csv"; break; diff --git a/Desktop/widgets/filemenu/filemenu.cpp b/Desktop/widgets/filemenu/filemenu.cpp index f6702aa28c..a2e5b8f4e6 100644 --- a/Desktop/widgets/filemenu/filemenu.cpp +++ b/Desktop/widgets/filemenu/filemenu.cpp @@ -47,6 +47,7 @@ FileMenu::FileMenu(QObject *parent) : QObject(parent) connect(_resourceButtons, &ResourceButtons::selectedButtonChanged, this, &FileMenu::resourceButtonClicked ); connect(_currentDataFile, &CurrentDataFile::setCheckAutomaticSync, _mainWindow, &MainWindow::setCheckAutomaticSync ); + _actionButtons->setEnabled(ActionButtons::New, true); _actionButtons->setEnabled(ActionButtons::Open, true); _actionButtons->setEnabled(ActionButtons::Save, false); _actionButtons->setEnabled(ActionButtons::SaveAs, false); @@ -116,6 +117,15 @@ FileEvent *FileMenu::saveAs() return _computer->browseSave(); } +FileEvent *FileMenu::newData() +{ + FileEvent *event = new FileEvent(this, FileEvent::FileNew); + + dataSetIORequestHandler(event); + + return event; +} + FileEvent *FileMenu::save() { FileEvent *event = nullptr; @@ -162,7 +172,7 @@ void FileMenu::sync() tr("JASP has no associated data file to be synchronized with.\nDo you want to search for such a data file on your computer?\nNB: You can also set this data file via menu File/Sync Data."))) return; - path = MessageForwarder::browseOpenFile(tr("Find Data File"), "", tr("Data File").arg("*.csv *.txt *.tsv *.sav *.zsav *.ods *.dta *.por *.sas7bdat *.sas7bcat *.xpt")); + path = MessageForwarder::browseOpenFile(tr("Find Data File"), "", tr("Data File").arg("*.csv *.txt *.tsv *.sav *.zsav *.ods *.xls *.xlsx *.dta *.por *.sas7bdat *.sas7bcat *.xpt")); } _mainWindow->setCheckAutomaticSync(false); @@ -410,6 +420,9 @@ void FileMenu::actionButtonClicked(const ActionButtons::FileOperation action) else setMode(FileEvent::FileSave); break; + case ActionButtons::FileOperation::New: + newData(); + break; case ActionButtons::FileOperation::About: setVisible(false); diff --git a/Desktop/widgets/filemenu/filemenu.h b/Desktop/widgets/filemenu/filemenu.h index 85495c67e5..ae4719bc6c 100644 --- a/Desktop/widgets/filemenu/filemenu.h +++ b/Desktop/widgets/filemenu/filemenu.h @@ -71,6 +71,7 @@ class FileMenu : public QObject void setResourceButtonsVisibleFor(FileOperation fo); void setOnlineDataManager(OnlineDataManager *odm); + FileEvent * newData(); FileEvent * open(const QString &filepath); FileEvent * open(const Json::Value & databaseInfo); FileEvent * save(); diff --git a/Docs/development/img/installation-fail.png b/Docs/development/img/installation-fail.png new file mode 100644 index 0000000000..17c170f52b Binary files /dev/null and b/Docs/development/img/installation-fail.png differ diff --git a/Docs/development/img/puzzle.svg b/Docs/development/img/puzzle.svg new file mode 100644 index 0000000000..0161e33915 --- /dev/null +++ b/Docs/development/img/puzzle.svg @@ -0,0 +1,127 @@ + + + + + + + + + + + R package(Functionality) + QML files(Graphicalinterface) + jaspResults(Display outputs) + The 3 main elementsof a JASP module + + diff --git a/Docs/development/jasp-adding-module.md b/Docs/development/jasp-adding-module.md index 4de9fae305..720614d02b 100644 --- a/Docs/development/jasp-adding-module.md +++ b/Docs/development/jasp-adding-module.md @@ -1,8 +1,14 @@ -Guide to adding a module in JASP +Structure of a JASP module ================================ -The ability to add your own module to JASP is a recently added feature (as of 0.9.3) and we will take care to avoid introducing breaking changes. The basic idea of loadable modules in JASP is that they follow the general structure of an R-package. In fact, if you have an R-package it is relatively easy to convert this to a module. +The basic idea of loadable modules in JASP is that they follow the general structure of an R package. From now on, we'll assume the reader is familiar with R packaging. If not, check out these excellent materials: Software Carpentries' [R packaging course](https://carpentries-incubator.github.io/lesson-R-packaging/index.html) and, if you want to go deeper, the [R packages book](https://r-pkgs.org/). + +In a nutshell, a JASP module provides no more (and no less) than a user-friendly graphical interface for an underlying R package. See a graphical summary below: + +![](./img/puzzle.svg) + +The ability to add your own module to JASP is a recently added feature (as of 0.9.3). ## Structure A module folder should look as follows: diff --git a/Docs/development/jasp-build-guide-linux.md b/Docs/development/jasp-build-guide-linux.md index 56f432415b..b4bbbc1a6a 100644 --- a/Docs/development/jasp-build-guide-linux.md +++ b/Docs/development/jasp-build-guide-linux.md @@ -23,6 +23,8 @@ If you have not cloned the `jasp-desktop` repository, please head back to the [b - `sqlite`^1 - `V8` (for `jaspProcess`) - `zlib`^1 + - `freexl`^1 + - Qt (>= 6.7) - Qt Creator 13 @@ -38,7 +40,7 @@ Based on your system, you can install the mentioned libraries using your package On Ubuntu, you can use `apt`. ``` -sudo apt install libboost-dev libjsoncpp25 libjsoncpp-dev libarchive13 libarchive-dev libxcb-xkb-dev libxcb-xkb1 libxcb-xinerama0 libxcb-cursor0 libxkbcommon-dev libxkbcommon-x11-dev autoconf zlib1g zlib1g-dev cmake gfortran build-essential flex libssl-dev libgl1-mesa-dev libsqlite3-dev r-base libglpk-dev +sudo apt install libboost-dev libjsoncpp25 libjsoncpp-dev libarchive13 libarchive-dev libxcb-xkb-dev libxcb-xkb1 libxcb-xinerama0 libxcb-cursor0 libxkbcommon-dev libxkbcommon-x11-dev autoconf zlib1g zlib1g-dev cmake gfortran build-essential flex libssl-dev libgl1-mesa-dev libsqlite3-dev r-base libglpk-dev libminizip-dev libfreexl-dev ``` > ⚠️ Some of these libraries might not be up-to-date and as a result JASP will complain. If this happens, you need to download, make and install those libraries individually. Alternatively, you can use the [Linux version of Homebrew](https://docs.brew.sh/Homebrew-on-Linux) and install the up-to-dated libraries locally. @@ -47,10 +49,10 @@ On Manjaro / Arch ``` sudo pacman -Syu autoconf bison boost cmake gcc gcc-fortran git glpk flex jags jsoncpp libarchive openssl patchelf r readstat zlib -# Google's V8 is only available through the aur consider using an aur helper +# JAGS and Google's V8 are only available through the aur # Note that only jaspProcess requires V8 and V8 takes a lot of time to compile -# To install it using the `yay` aur helper run: -yay -Syu v8-r +# To install them using the `yay` aur helper run: +yay -Syu jags v8-r ``` On Fedora/RHEL @@ -86,15 +88,15 @@ You also need Qt Creator and Qt 6 to be able to build and test JASP's libraries - [x] CMake - [x] Ninja -### ReadStat and JAGS +### Dependencies -On Linux JASP's CMake script will download and install ReadStat and JAGS for you when necessary. +On Linux JASP's CMake script will download and install ReadStat, JAGS and FreeXL for you when necessary. ### Installing Qt Creator / Qt Similar to Windows and macOS, you can download and install the Qt Framework from Qt website, [here](https://www.qt.io/download). -> 💡 Sometimes, dependeing on your Linux distribution, you might be able to get the Qt libraries using your package manger. For instance, if you are running any variant of an Arch Linux, e.g., Manjaro, `pacman` readily offers the latest build of the Qt libraries, and you can download it by running the following command, `pacman -Syu qt6`. +> 💡 Sometimes, dependeing on your Linux distribution, you might be able to get the Qt libraries using your package manager. For instance, if you are running any variant of an Arch Linux, e.g., Manjaro, `pacman` readily offers the latest build of the Qt libraries, and you can download it by running the following command, `pacman -Syu qt6`. ### Configuring and Building JASP Desktop diff --git a/Docs/development/jasp-module-workflow.md b/Docs/development/jasp-module-workflow.md index 6b10ae14ba..3c64599728 100644 --- a/Docs/development/jasp-module-workflow.md +++ b/Docs/development/jasp-module-workflow.md @@ -1,14 +1,59 @@ # Developing workflow in JASP for modules So you want to develop a module for JASP? Great! -## Windows & macOs -The easiest way to do so is downloading the latest [nightly for your system](http://static.jasp-stats.org/Nightlies/) or (a bit harder) [building jasp yourself](./jasp-building-guide.md). +## Step 1. Install a latest version of JASP -## Linux -To develop on Linux you currently need to compile JASP from source. We have a guide on how to do that [here](https://github.com/jasp-stats/jasp-desktop/blob/development/Docs/development/jasp-building-guide.md). +### Windows & macOs +The easiest way to do so is downloading the latest [nightly for your system](http://static.jasp-stats.org/Nightlies/). -## Development Process -Then you either create a new module repository [based on this template](https://github.com/jasp-stats/jaspModuleTemplate) or by forking one of the existing modules in [jasp-stats](https://github.com/jasp-stats). +### Linux + +0. Installing JASP in Linux requires flatpak. Please follow [this link](https://flatpak.org/setup/) if you haven't installed it yet. +1. Add the `flathub-beta` repository with: + +```sh +flatpak remote-add --if-not-exists flathub-beta https://flathub.org/beta-repo/flathub-beta.flatpakrepo +``` + +3. Install the latest jasp beta with: + +```sh +flatpak install flathub-beta org.jaspstats.JASP +``` + +4. Open it in development mode: + +```sh +flatpak run --branch=beta --devel org.jaspstats.JASP +``` + +> [!WARNING] +> JASP will remember from which branch it was launched. +> To go back to the "normal" jasp, run: +> ```sh +> flatpak run --branch=stable org.jaspstats.JASP +> ``` + +#### Problems? +Some users experienced the following error: +```sh +error: runtime/org.kde.Sdk/x86_64/6.7 not installed +``` +This can be fixed by manually installing the missing runtime: +```sh +flatpak install org.kde.Sdk +``` +and choosing the appropriate version (`6.7` in this example). + +### From source (advanced) +In case you want to go the hard way and compile JASP from source, please follow our JASP building guides: + +- [For Windows](./jasp-build-guide-windows.md) +- [For macOS](./jasp-build-guide-macos.md) +- [For Linux](./jasp-build-guide-linux.md) + +## Step 2. Develop your module +Then you either create a new module repository [based on this template](https://github.com/jasp-stats/jaspModuleTemplate) or by forking one of the existing modules in [jasp-stats](https://github.com/jasp-stats). For example, you can create the fork by downloading the .ZIP and repackage it as a TAR.GZ. To start developing your own module you should first understand the [structure of a module](jasp-adding-module.md). Initially you do not need to add any of the .qml, .R or icon files, but you should minimally have the Description.qml, DESCRIPTION and NAMESPACE. @@ -29,6 +74,17 @@ Before creating any of the other files you should now add the module folder in J 2. Click on the plus symbol in the top right corner 3. Click on Install Developer Module +### Problems? +If you are experiencing an error similar to the one below: + +![](./img/installation-fail.png) + +very likely GitHub is stopping you from cloning multiple repositories at the same time. + +The fix is to configure a GitHub [Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token) (PAT). The only purpose is to identify yourself as a legit user, so a token with no permissions will suffice. + +When you have it, go to `Preferences/Advanced`, untick `Use default PAT for Github` and paste your recently created token there. Don't forget to press `Enter` or `tab` to make sure the changes were saved! + ### Developing the module At this point you can start adding the various files the module requires. It is advisable to start with the .qml interface file before adding the analysis in R. @@ -38,7 +94,7 @@ Similarly, if you change the title of your module in the .json file this will im As such JASP becomes a development tool, making it much easier to check your changes are correct as you make them. It might take a little while to see changes in R though, because JASP needs to rebuild the package and install it internally. So try to be patient with it ;) -## Distributing the module +## Step 3. Distribute your module In case you made a fork of an existing module all you need to do is open a PR to the original repository. Once your code is merged it will show up in the next nightly of JASP (or in your `jasp-desktop` folder if you build from source and run `git submodule update --remote`). @@ -53,12 +109,11 @@ cd /to/your/module/repository/directory git tag -a v1.0 #It will open an editor where you can add some information on your release git push -u origin v1.0 ``` -If you now go to your GitHub repository you can select `Releases` and download the generated .tar.gz, see the following, ahum, visual guide for more details: -![Visual guide to finding a generated .tar.gz on GitHub](/Docs/development/img/FindingModuleTarGz.png) +If you now go to your GitHub repository you can select `Releases` within the right hand side panel. There you can download the tar.gz. ##### "Hard" way On linux and MacOS this is not so bad: simply open up a terminal and go to the directory containing your module and enter the following: "`tar -czf .tar.gz `". On Windows this is a bit more complicated but can be done through [7zip](https://www.7-zip.org/), first your select you folder `` and compress it to a `.tar` file and then you select that file and compress it to a `.gz` or "gzip" file leaving you with `.tar.gz`. -As you can see this implies that the folder containing your module-files has the same name as your module (aka what is specified in the field `name` in [Description.qml](#Description.qml) or in the `Package` field of [DESCRIPTION](#package-metadata). +This implies that the folder containing your module-files has the same name as your module (aka what is specified in the field `name` in [Description.qml](#Description.qml) or in the `Package` field of [DESCRIPTION](#package-metadata). diff --git a/Docs/development/jasp-qml-guide.md b/Docs/development/jasp-qml-guide.md index b4246fdcae..2b3d6933f5 100644 --- a/Docs/development/jasp-qml-guide.md +++ b/Docs/development/jasp-qml-guide.md @@ -56,12 +56,15 @@ Table of Contents: The components can roughly be divided in three classes. One that deals with general inputs (e.g., checkboxes), one that deals with assigning variables and one that groups components together. Each will be covered in the following section. Some remarks about these components: - They are all QML items, so they automatically get generic QML properties like `enabled` or `visible`. -- In several examples you may encounter `qsTr()`, it is important that this function wraps around all user-visible text, this function makes translating the interface possible. +- In several examples you may encounter `qsTr()`, it is important that this function wraps around all user-visible text, this function makes translating the interface possible. If you use non-latin characters, it is then better to use the `\uXXXX` encoding (XXXX being the Unicode code point of the character), to be sure that that it passes the translation process (avoid the HTML encoding `&#xxx;`). - The components described below may generally be nested to an arbitrary level (e.g., a checkbox in a group in a checkbox). ### Name All (well almost all) of these components have a property `name` that is also used in JASP-files to store the value the user selected. That means that whenever you change `name` for a component for a newer version of your analysis/module the stored value will be ignored. To make sure the user entered information isn't lost you can add an [Upgrades.qml to your module](jasp-upgrade-qml.md). +### Label or title +Most of the components have a label or a title (each word of a title should be capitalized). Unlike the name, the label or title must be translated via the `qsTr()` function. For non-latin characters, use the `\uXXXX` encoding. + ### Info Each component also has a field called `info` which is used to generate documentation from. By wrapping the text in the above mentioned `qsTr` this also allows us to translate the documentation for each module in parts. So you would have something like: ``` @@ -445,14 +448,7 @@ Properties - `name`: identifier of the particular variable field (in your R code you will be able to retrieve the assigned variable(s) through this identifier) - `label`: [optional, default: `""`] text that will be shown above the variable field - `columns`: [optional, default: 1] number of columns of the list. -- `allowedColumns`: [optional, default: empty, possible values: `["scale", "ordinal", "nominal"]` ] array specifying the allowed column types. -- `suggestedColumns`: [optional, default: empty, possible values: `["scale", "ordinal", "nominal"]` ] array specifying the suggested column types. The difference between `allowedColumns` and `suggestedColumns` is that `allowedColumns` sets explicitly the types that are allowed, and `suggestedColumns` sets the allowed types in a looser way, with these rules: - * if `suggestedColumns` contains the `scale` type, then `nominal` and `ordinal` types are also allowed - * if `suggestedColumns` contains the `nominal` type, then `ordinal` tyes are also allowed - -The `suggestedColumns` types are displayed as icons at the bottom-right of the VariablesList, indicating which kind of columns may be added in this VariablesList. If `suggestedColumns` is empty and `allowedColumns` is specified, then the `allowedColumns` is used to display the type icons. -If `suggestedColumns` and `allowedColumns` are empty, then all column types are allowed.\ -To avoid confusion, use either the `allowedColumns` property or the `suggestedColumns` property, and not both properties, to set which columns might be inserted in the VariablesList. `allowedColumns` sets the types explicitly, `suggestedColumns` indicates more which types should be used, but permits other types that can be converted implicitly to the right type. +- `allowedColumns`: [optional, default: empty, possible values: `["scale", "ordinal", "nominal"]` ] array specifying the allowed column types, which displayed as icons at the bottom-right of the VariablesList. Other type of columns can be converted automatically to the right type, all column types would be allowed if set it empty. - `maxRows`: [optional, default: `-1`] maximum number of rows the list can accept. -1 means no limit. - `singleVariable`: [optional, default: `false`] if true, set the maxRows to 1 - `listViewType`: [optional] enumerative that specifies the type of `AssignedVariablesList`, when omitted we get a normal list, options are `JASP.Layers` (see Contingency Tables), `JASP.Interaction` (see ANOVA) and `JASP.RepeatedMeasures` (see Repeated Measures ANOVA) diff --git a/Docs/development/jasp-qml-style-example.qml b/Docs/development/jasp-qml-style-example.qml index 9aa01f499f..1a8638cce0 100644 --- a/Docs/development/jasp-qml-style-example.qml +++ b/Docs/development/jasp-qml-style-example.qml @@ -47,7 +47,7 @@ Form { AvailableVariablesList { name: "availbleVariables" } AssignedVariablesList { name: "variables"; title: qsTr("Variables") } - AssignedVariablesList { name: "splitby"; title: qsTr("Split"); singleVariable: true; suggestedColumns: ["ordinal", "nominal"] } + AssignedVariablesList { name: "splitby"; title: qsTr("Split"); singleVariable: true; allowedColumns: ["ordinal", "nominal"] } } //But in most cases you should follow the style documented at "theRightWayForSpecifyingProperties" diff --git a/Docs/development/windows-installer.md b/Docs/development/windows-installer.md index f00f264f3b..f8f9d60147 100644 --- a/Docs/development/windows-installer.md +++ b/Docs/development/windows-installer.md @@ -45,7 +45,7 @@ The generated MSIX for the Microsoft Store will be unsigned and must be provided The MSIXs can be generated after building JASP by running the following commands in your JASP build folder: ``` -cmake --build . --target windowsPreInstallHacks && cmake --build . --target install && cmake --build . --target collect-junctions && cmake --install . --component MSIX && cmake --build . --target msix +cmake --build . --target install && cmake --build . --target collect-junctions && cmake --install . --component MSIX && cmake --build . --target msix ``` This is subject to change, for an up to date sequence take a peak at the [buildbot-script](/Tools/windows/BuildBotScript.cmd). diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt index bfa5030a85..d2f87aac6d 100644 --- a/Engine/CMakeLists.txt +++ b/Engine/CMakeLists.txt @@ -107,16 +107,14 @@ if(WINDOWS) POST_BUILD DEPENDS ${CMAKE_BINARY_DIR}/R-Interface/libR-Interface.dll COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_LIBGCC_S_SEH_DLL} ${CMAKE_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_LIBSTDCPP_DLL} - ${CMAKE_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_MSYS_DLL} - ${CMAKE_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_LIBSTDCPP_DLL} + ${CMAKE_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_MSYS_DLL} + ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_LIBWINPTHREAD_DLL} ${CMAKE_BINARY_DIR} - #COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_LIBJSONCPP_DLL} - # ${CMAKE_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_LIBREADSTAT_DLL} - ${CMAKE_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_LIBREADSTAT_DLL} + ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_ZLIB_DLL} ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RTOOLS_LIBICONV_DLL} diff --git a/Engine/engine.cpp b/Engine/engine.cpp index fde68b8acf..23b9b21461 100644 --- a/Engine/engine.cpp +++ b/Engine/engine.cpp @@ -481,8 +481,15 @@ void Engine::receiveModuleRequestMessage(const Json::Value & jsonRequest) std::string moduleRequest = jsonRequest["moduleRequest"].asString(); std::string moduleCode = jsonRequest["moduleCode"].asString(); std::string moduleName = jsonRequest["moduleName"].asString(); + std::string moduleLibPaths = jsonRequest["moduleLibPaths"].asString(); - Log::log() << "About to run module request for module '" << moduleName << "' and code to run:\n'" << moduleCode << "'" << std::endl; + Log::log() << "About to run module request for module '" << moduleName << "' and code to run:\n'" << moduleCode << "'" << std::endl; + + if(moduleStatusFromString((moduleRequest)) == moduleStatus::loading) { + //Some jaspModules use jaspBase calls in their .onload so we first we need to prepare jaspbase + jaspRCPP_evalRCode((".libPaths( " + moduleLibPaths + " );").c_str(), false); + jaspRCPP_init_jaspBase(); + } std::string result = jaspRCPP_evalRCode(moduleCode.c_str(), false); bool succes = result == "succes!"; //Defined in DynamicModule::succesResultString() diff --git a/Engine/jaspBase b/Engine/jaspBase index 7de02c4424..24d4ae8eb2 160000 --- a/Engine/jaspBase +++ b/Engine/jaspBase @@ -1 +1 @@ -Subproject commit 7de02c442478e028fe2036e3b906059bf504c13e +Subproject commit 24d4ae8eb2efcaae974b6c900ebf1c64020bb90e diff --git a/Engine/jaspGraphs b/Engine/jaspGraphs index e439c080e3..b2e1799265 160000 --- a/Engine/jaspGraphs +++ b/Engine/jaspGraphs @@ -1 +1 @@ -Subproject commit e439c080e3841e0719c00ce35c376b34c833b546 +Subproject commit b2e1799265a0741b49a1ca356f96448091dd8db0 diff --git a/Engine/jaspModuleInstaller b/Engine/jaspModuleInstaller new file mode 160000 index 0000000000..8d0666d706 --- /dev/null +++ b/Engine/jaspModuleInstaller @@ -0,0 +1 @@ +Subproject commit 8d0666d70641bd3515eb05cd231ac3647b894fc9 diff --git a/Engine/rbridge.cpp b/Engine/rbridge.cpp index b61f820270..974aeae888 100644 --- a/Engine/rbridge.cpp +++ b/Engine/rbridge.cpp @@ -760,7 +760,7 @@ std::string rbridge_evalRComputedColumn(const std::string &rCode, const std::str jaspRCPP_resetErrorMsg(); - std::string rCode64( rbridge_encodeColumnNamesInScript(rCode)); + std::string rCode64( "library(jaspBase);\n" + rbridge_encodeColumnNamesInScript(rCode)); try { R_FunctionWhiteList::scriptIsSafe(rCode64); } catch(filterException & e) { jaspRCPP_setErrorMsg(e.what()); return std::string("R code is not safe because of: ") + e.what(); } diff --git a/Modules/Rcpp_RInside.lock b/Modules/Rcpp_RInside.lock new file mode 100644 index 0000000000..adb746136d --- /dev/null +++ b/Modules/Rcpp_RInside.lock @@ -0,0 +1,23 @@ +{ + "R": { + "Version": "4.3.3", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cran.rstudio.com" + } + ] + }, + "Packages": { + "RInside": { + "Package": "RInside", + "Version": "0.2.18", + "Source": "Repository" + }, + "Rcpp": { + "Package": "Rcpp", + "Version": "1.0.12", + "Source": "Repository" + } + } +} diff --git a/Modules/install-RInside.R.in b/Modules/install-RInside.R.in deleted file mode 100644 index 00d7b6ae44..0000000000 --- a/Modules/install-RInside.R.in +++ /dev/null @@ -1,11 +0,0 @@ -# Generated from install-RInside.R.in -# -# Installs `RInside` and `Rcpp`. While `Rcpp` is a dependency of the `RInside`, -# I've ran into situation where installing `RInside` doesn't install the `Rcpp`. -# - -Sys.setenv(MAKEFLAGS="-j") - -.libPaths(c("@R_LIBRARY_PATH@")) -#We need building from source on linux in any case and on windows because otherwise lots of CRAN env-vars get baked into RInside... -install.packages(c('RInside', 'Rcpp'), type = ifelse(Sys.info()["sysname"] == "Darwin", "binary", "source"), lib='@R_LIBRARY_PATH@', repos='@R_REPOSITORY@', INSTALL_opts='--no-multiarch --no-docs --no-test-load') \ No newline at end of file diff --git a/Modules/install-jaspBase.R.in b/Modules/install-jaspBase.R.in deleted file mode 100644 index 338f6ccaa6..0000000000 --- a/Modules/install-jaspBase.R.in +++ /dev/null @@ -1,54 +0,0 @@ -# Generated from install-jaspBase.R.in -# -Sys.setenv(GITHUB_PAT="@GITHUB_PAT@") -Sys.setenv(RENV_PATHS_ROOT="@MODULES_RENV_ROOT_PATH@") -Sys.setenv(RENV_PATHS_CACHE="@MODULES_RENV_CACHE_PATH@") -Sys.setenv(JASPENGINE_LOCATION="@JASP_ENGINE_PATH@/JASPEngine") -Sys.setenv(MAKEFLAGS="-j") - -#Load the post-install fixes from jaspBase. Think Baron von Munchausen ;) -source("@PROJECT_SOURCE_DIR@/Engine/jaspBase/R/utility.R") -source("@PROJECT_SOURCE_DIR@/Engine/jaspBase/R/checkSums.R") -source("@PROJECT_SOURCE_DIR@/Engine/jaspBase/R/assignFunctionInPackage.R") -source("@PROJECT_SOURCE_DIR@/Engine/jaspBase/R/moduleInstall.R") - -# The R_LIBRARY_PATH might already be there, but depending on the configuration -# of the CMake, we might be installing in a different location, so, I just add -# it anyway! It gets to if-y. - -if (@IS_FLATPAK_USED@) { - source("/app/lib64/Rprofile.R") - options(repos = "@R_REPOSITORY@") -} - -.libPaths(c("@R_LIBRARY_PATH@")) - -modulePkg <- "@PROJECT_SOURCE_DIR@/Engine/jaspBase" -moduleLibrary <- "@R_LIBRARY_PATH@" -prompt <- FALSE - -if (md5SumsChanged(modulePkg, moduleLibrary)) { - options( - renv.cache.linkable = FALSE, - configure.vars = c(jaspBase = "INCLUDE_DIR='@PROJECT_SOURCE_DIR@/Common/jaspColumnEncoder'") - ) - - Sys.setenv(JASP_R_INTERFACE_LIBRARY="Oh yes indeed") - setupRenv("@R_LIBRARY_PATH@", modulePkg) - - renv::hydrate(library = moduleLibrary, project = modulePkg, sources=moduleLibrary) - options(renv.config.install.verbose = TRUE) - renv::install(package = modulePkg, project = modulePkg, library = moduleLibrary, prompt = prompt) - - correctlyInstalled <- installModulePkg(modulePkg, moduleLibrary, prompt, cacheAble=TRUE) - - if (correctlyInstalled) - writeMd5Sums(modulePkg, moduleLibrary) -} - -# Converting the absolute symlinks to relative symlinks on macOS -# Todo, I can do this using CMake like I do on Windows -if (Sys.info()["sysname"] == "Darwin") { - source('@MODULES_BINARY_PATH@/symlinkTools.R') - convertAbsoluteSymlinksToRelative('@R_LIBRARY_PATH@', '@MODULES_RENV_CACHE_PATH@') -} diff --git a/Modules/install-jaspModuleInstaller.R.in b/Modules/install-jaspModuleInstaller.R.in new file mode 100644 index 0000000000..8e1b11e7af --- /dev/null +++ b/Modules/install-jaspModuleInstaller.R.in @@ -0,0 +1,105 @@ +# Generated from install-jaspBase.R.in +# +Sys.setenv(GITHUB_PAT = "@GITHUB_PAT@") +Sys.setenv(RENV_PATHS_ROOT = "@MODULES_RENV_ROOT_PATH@") +Sys.setenv(RENV_PATHS_CACHE = "@MODULES_RENV_CACHE_PATH@") +Sys.setenv(RENV_PATHS_SANDBOX = "@RENV_SANDBOX@") +Sys.setenv(JASPENGINE_LOCATION = "@JASP_ENGINE_PATH@/JASPEngine") + +if("@R_PKG_CELLAR_PATH@" != "") + Sys.setenv(RENV_PATHS_CELLAR = "@R_PKG_CELLAR_PATH@") + + +#Load the post-install fixes from jaspBase. Think Baron von Munchhausen ;) +source("@PROJECT_SOURCE_DIR@/Engine/jaspModuleInstaller/R/renvOverrides.R") +source("@PROJECT_SOURCE_DIR@/Engine/jaspModuleInstaller/R/checksums.R") +source("@PROJECT_SOURCE_DIR@/Engine/jaspModuleInstaller/R/utils.R") +source("@PROJECT_SOURCE_DIR@/Engine/jaspModuleInstaller/R/installModule.R") + +# The R_LIBRARY_PATH might already be there, but depending on the configuration +# of the CMake, we might be installing in a different location, so, I just add +# it anyway! It gets to if-y. + + +.libPaths("@RENV_LIBRARY@") +sandboxPaths <- renv:::renv_sandbox_activate() + +JASPMODULEINSTALLER_LIBRARY <- "@JASPMODULEINSTALLER_LIBRARY@" +PKGDEPENDS_LIBRARY <- "@PKGDEPENDS_LIBRARY@" +RENV_LIBRARY <- "@RENV_LIBRARY@" +R_CPP_INCLUDES_LIBRARY <- "@R_CPP_INCLUDES_LIBRARY@" +JUNCTION_HANDLING_LIBRARY <- "@JUNCTION_HANDLING_LIBRARY@" + +ENGINE <- file.path("@PROJECT_SOURCE_DIR@", "Engine") +MODULES <- file.path("@PROJECT_SOURCE_DIR@", "Modules") +TOOLS <- file.path("@PROJECT_SOURCE_DIR@", "Tools") + + +modulePkg <- file.path("@PROJECT_SOURCE_DIR@", "Engine", "jaspModuleInstaller") + +cat("Restoring pkgdepends\n") +setupRenv(PKGDEPENDS_LIBRARY) +renv::restore( + library = PKGDEPENDS_LIBRARY, + lockfile = file.path(MODULES, "pkgdepends.lock"), + clean = TRUE +) + +if (.Platform$OS.type == "windows") { + cat("Restoring junction handling library\n") + options(renv.config.cache.symlinks = FALSE) + setupRenv(JUNCTION_HANDLING_LIBRARY) + renv::restore( + library = JUNCTION_HANDLING_LIBRARY, + lockfile = file.path(MODULES, "junctionBootstrap.lock"), + clean = TRUE + ) +} + +cat("Restoring jaspModuleInstaller\n") +options(renv.config.cache.symlinks = TRUE) +setupRenv(JASPMODULEINSTALLER_LIBRARY) +renv::restore( + library = JASPMODULEINSTALLER_LIBRARY, + lockfile = file.path(ENGINE, "jaspModuleInstaller", "renv.lock"), + exclude = "jaspModuleInstaller", # otherwise "clean" would remove jaspModuleInstaller + clean = TRUE +) + +print("Installing jaspModuleInstaller") +.libPaths(JASPMODULEINSTALLER_LIBRARY) +setupRenv("@R_LIBRARY_PATH@", modulePkg) + +record <- createLocalRecord(modulePkg, getModuleInfo(modulePkg), cacheAble = FALSE, addJaspToVersion = FALSE) +lf <- renv::lockfile_read(file.path(modulePkg, "renv.lock")) +lf <- renv::record(record, lockfile = lf) +cat(".libPaths()", .libPaths(), sep = "\n") + +# remove the package if it is installed, otherwise renv doesn't realize we want to reinstall it +pkgName <- basename(modulePkg) +if (dir.exists(file.path(.libPaths()[1L], pkgName))) + utils::remove.packages(pkgs = pkgName, lib = .libPaths()[1L]) + +renv::restore(lockfile = lf, library = .libPaths(), rebuild = pkgName) + + + +print("jaspModuleInstaller::writeModuleStatusObject(@PROJECT_SOURCE_DIR@") +jaspModuleInstaller::writeModuleStatusObject("@PROJECT_SOURCE_DIR@") +#This is necessary because of conflicts with Matrix dep of base R lib. +#Can be removed when a new version of R updates its Matrix +if (!@IS_FLATPAK_USED@) { + + if (Sys.info()["sysname"] == "Darwin") { + options(pkgType = "source") + } + + renv::install("Matrix", library = JASPMODULEINSTALLER_LIBRARY, prompt = FALSE) +} + +# Converting the absolute symlinks to relative symlinks on macOS +# Todo, I can do this using CMake like I do on Windows +if (Sys.info()["sysname"] == "Darwin") { + source('@MODULES_BINARY_PATH@/Tools/symlinkTools.R') + convertAbsoluteSymlinksToRelative('@R_LIBRARY_PATH@', '@MODULES_RENV_CACHE_PATH@') +} diff --git a/Modules/install-module.R.in b/Modules/install-module.R.in index 3186b3c304..bbbb0ca730 100644 --- a/Modules/install-module.R.in +++ b/Modules/install-module.R.in @@ -11,6 +11,14 @@ Sys.setenv(JAGS_PREFIX ="@jags_HOME@") Sys.setenv(JAGS_INCLUDEDIR ="@jags_INCLUDE_DIRS@") Sys.setenv(JAGS_LIBDIR ="@jags_LIBRARY_DIRS@") Sys.setenv(JASP_R_INTERFACE_LIBRARY ="Yes, do it") +Sys.setenv(RPKG_DOWNLOAD_ONLY = "@RPKG_DOWNLOAD_ONLY@") +Sys.setenv(REGENERATE_LOCKFILE = "@REGENERATE_LOCKFILE@") +Sys.setenv(MODULE_INSTALL_MODE = "@MODULE_INSTALL_MODE@") + + + +if("@R_PKG_CELLAR_PATH@" != "") + Sys.setenv(RENV_PATHS_CELLAR = "@R_PKG_CELLAR_PATH@") defaultMakeFlags <- function() { Sys.setenv(MAKEFLAGS = "-j" ) } setMakeFlagsToOne <- function() { Sys.setenv(MAKEFLAGS = "-j1") } @@ -21,51 +29,49 @@ options("JASP_RENV_INSTALL_OPTIONS" = list( blavaan = list(before = setMakeFlagsToOne, after = defaultMakeFlags), metaBMA = list(before = setMakeFlagsToOne, after = defaultMakeFlags), rstanarm = list(before = setMakeFlagsToOne, after = defaultMakeFlags), - stanova = list(before = setMakeFlagsToOne, after = defaultMakeFlags) - + stanova = list(before = setMakeFlagsToOne, after = defaultMakeFlags), + rpf = list(before = setMakeFlagsToOne, after = defaultMakeFlags), + cubature = list(before = setMakeFlagsToOne, after = defaultMakeFlags), + OpenMx = list(before = setMakeFlagsToOne, after = defaultMakeFlags) )) options(renv.config.install.verbose = TRUE) +configureVars = NULL if (@IS_LINUX_LOCAL_BUILD@) { - # Only set when building using LINUX_LOCAL_BUILD. This is to help jags finds its libraries - Sys.setenv(LD_LIBRARY_PATH="@jags_LIBRARY_DIRS@") -} - - -if (@IS_FLATPAK_USED@) { - source('/app/lib64/Rprofile.R'); + # Only set when building using LINUX_LOCAL_BUILD. This is to help jags finds its libraries + Sys.setenv(LD_LIBRARY_PATH="@jags_LIBRARY_DIRS@") + configureVars = c(V8 = 'DOWNLOAD_STATIC_LIBV8=1') +} +if(@IS_FLATPAK_USED@) { + configureVars = c(V8 = "V8_PKG_LIBS='-L/app/lib64/v8/lib -lv8_monolith' V8_PKG_CFLAGS=-I/app/lib64/v8/include") } -# The R_LIBRARY_PATH might already be there, but depending on the configuration -# of the CMake, we might be installing in a different location, so, I just add -# it anyway! It gets to if-y. -.libPaths(c("@R_LIBRARY_PATH@")) +.libPaths("@JASPMODULEINSTALLER_LIBRARY@") +sandboxPaths <- renv:::renv_sandbox_activate() +configureVars = c(configureVars, jaspBase = "INCLUDE_DIR='@PROJECT_SOURCE_DIR@/Common/jaspColumnEncoder'") #Needed for flatpak build as it keeps recompiling jaspBase (which it shouldnt of course but I dont know why) and this is an easy fix to get it to work now options( - configure.vars = c(jaspBase = "INCLUDE_DIR='@PROJECT_SOURCE_DIR@/Common/jaspColumnEncoder'") #Needed for flatpak build as it keeps recompiling jaspBase (which it shouldnt of course but I dont know why) and this is an easy fix to get it to work now + configure.vars = configureVars, + PKGDEPENDS_LIBRARY = "@PKGDEPENDS_LIBRARY@" ) -if (jaspBase::getOS() == "osx" || jaspBase::getOS() == "windows") { - options(pkgType = "@R_BINARY_TYPE@") -} - -# Related to the comment above, there is variable here called, -# `libPathsToUse` but it is not connected to anything. If this works, -# then, I don't need to set the libPaths() anymore perhaps. -result <- jaspBase::installJaspModule("@MODULES_SOURCE_PATH@/@MODULE@", - repos="@R_REPOSITORY@", - moduleLibrary="@MODULES_BINARY_PATH@/@MODULE@", - onlyModPkg=FALSE, - libPathsToUse='', - frameworkLibrary="@R_LIBRARY_PATH@") +options(error = recover) +jaspModuleInstaller::installJaspModule( + modulePkg = "@MODULES_SOURCE_PATH@/@MODULE@", + repos = "@R_REPOSITORY@", + moduleLibrary = "@MODULES_BINARY_PATH@/@MODULE@", + onlyModPkg = FALSE, + frameworkLibrary = "@R_LIBRARY_PATH@" +) +result <- "succes" if (result == "succes") { - cat(NULL, file="@MODULES_RENV_ROOT_PATH@/@MODULE@-installed-successfully.log") + cat(NULL, file="@MODULES_RENV_ROOT_PATH@/@MODULE@-installed-successfully.log") } # Converting the absolute symlinks to relative symlinks on macOS # Todo, I can do this using CMake like I do on Windows -if (Sys.info()["sysname"] == "Darwin") { - source('@MODULES_BINARY_PATH@/symlinkTools.R') - convertAbsoluteSymlinksToRelative('@MODULES_BINARY_PATH@', '@MODULES_RENV_CACHE_PATH@') +if (Sys.info()["sysname"] == "Darwin") { + source('@MODULES_BINARY_PATH@/Tools/symlinkTools.R') + convertAbsoluteSymlinksToRelative('@MODULES_BINARY_PATH@', '@MODULES_RENV_CACHE_PATH@') } diff --git a/Modules/install-renv.R.in b/Modules/install-renv.R.in deleted file mode 100644 index 22162772de..0000000000 --- a/Modules/install-renv.R.in +++ /dev/null @@ -1,6 +0,0 @@ -# Generated from install-renv.R.in -# -.libPaths(c("@R_LIBRARY_PATH@")) - -install.packages(c('renv'), lib='@R_LIBRARY_PATH@', repos='@R_REPOSITORY@', INSTALL_opts='--no-multiarch --no-docs --no-test-load') -#remotes::install_github("vandenman/renv", ref="fix_multiple_cache_error", lib='@R_LIBRARY_PATH@', repos='@R_REPOSITORY@', INSTALL_opts='--no-multiarch --no-docs --no-test-load') diff --git a/Modules/jaspAcceptanceSampling b/Modules/jaspAcceptanceSampling index 5259cfc1c3..611e479094 160000 --- a/Modules/jaspAcceptanceSampling +++ b/Modules/jaspAcceptanceSampling @@ -1 +1 @@ -Subproject commit 5259cfc1c331e5cf7ea1107a9d3b9f427cfe8afb +Subproject commit 611e479094ee6ca336c96ab0a0d4887865b0bece diff --git a/Modules/jaspAnova b/Modules/jaspAnova index 1172c95396..edb8a9af89 160000 --- a/Modules/jaspAnova +++ b/Modules/jaspAnova @@ -1 +1 @@ -Subproject commit 1172c953966e53789496d21fa684af46fec49135 +Subproject commit edb8a9af89883ad8c0fef79f9c1f7d60dff67476 diff --git a/Modules/jaspAudit b/Modules/jaspAudit index 28c7640677..6c4a9c6f18 160000 --- a/Modules/jaspAudit +++ b/Modules/jaspAudit @@ -1 +1 @@ -Subproject commit 28c764067725e162d9f5af628e02546333f6406a +Subproject commit 6c4a9c6f189a072b6059472e7102a496c18debf2 diff --git a/Modules/jaspBFF b/Modules/jaspBFF new file mode 160000 index 0000000000..b8d32004ab --- /dev/null +++ b/Modules/jaspBFF @@ -0,0 +1 @@ +Subproject commit b8d32004ab408b0f06194f9d9e519def0ea9a253 diff --git a/Modules/jaspBain b/Modules/jaspBain index b5ca75ad61..16df5ef2ea 160000 --- a/Modules/jaspBain +++ b/Modules/jaspBain @@ -1 +1 @@ -Subproject commit b5ca75ad61e53560a26e2caa2d86f5e74dde2ff2 +Subproject commit 16df5ef2ea0edabeb6ac76d58242a4bc70fba564 diff --git a/Modules/jaspBsts b/Modules/jaspBsts index 5879d2fabf..e19738adbd 160000 --- a/Modules/jaspBsts +++ b/Modules/jaspBsts @@ -1 +1 @@ -Subproject commit 5879d2fabf59e29f664ba458a1d8a4951cee54be +Subproject commit e19738adbd12e93d5df8327cb3c4e0e39de14d53 diff --git a/Modules/jaspCircular b/Modules/jaspCircular index 2bf11feb81..42b037face 160000 --- a/Modules/jaspCircular +++ b/Modules/jaspCircular @@ -1 +1 @@ -Subproject commit 2bf11feb81ada6872a2117f748819025e5a89d00 +Subproject commit 42b037facecd1f4f0914e5d81344cd6d707e5fbc diff --git a/Modules/jaspCochrane b/Modules/jaspCochrane index 9728819a60..587a6a4a13 160000 --- a/Modules/jaspCochrane +++ b/Modules/jaspCochrane @@ -1 +1 @@ -Subproject commit 9728819a60d005295a7bfd8b805e6d47d35705b8 +Subproject commit 587a6a4a13528d838755b4bb078fe33e39dacb77 diff --git a/Modules/jaspDescriptives b/Modules/jaspDescriptives index f6ba4aa4c9..28b939b802 160000 --- a/Modules/jaspDescriptives +++ b/Modules/jaspDescriptives @@ -1 +1 @@ -Subproject commit f6ba4aa4c933febecf2ff3a8c81e9af3341a451a +Subproject commit 28b939b802e973de39162b6633610180f5bd011c diff --git a/Modules/jaspDistributions b/Modules/jaspDistributions index afc50c8cad..5447c6554b 160000 --- a/Modules/jaspDistributions +++ b/Modules/jaspDistributions @@ -1 +1 @@ -Subproject commit afc50c8cadb1fbb3990f8cb78c8aff836c98bc0e +Subproject commit 5447c6554b5c0f58b00b0887d0888012289a7ce1 diff --git a/Modules/jaspEquivalenceTTests b/Modules/jaspEquivalenceTTests index 26ec4008c9..1c953381c7 160000 --- a/Modules/jaspEquivalenceTTests +++ b/Modules/jaspEquivalenceTTests @@ -1 +1 @@ -Subproject commit 26ec4008c9b8311e59e3f07e9cfb8f5b069acb82 +Subproject commit 1c953381c7ad48121c37a7d39e30d42dde33e8e2 diff --git a/Modules/jaspFactor b/Modules/jaspFactor index 656d329a58..63f5828fa9 160000 --- a/Modules/jaspFactor +++ b/Modules/jaspFactor @@ -1 +1 @@ -Subproject commit 656d329a5899658bd04c4e46a9aa56b54b0ca7ff +Subproject commit 63f5828fa91358b5e63b820db7f087ebbf6cae68 diff --git a/Modules/jaspFrequencies b/Modules/jaspFrequencies index f94529d357..dbc8094ea7 160000 --- a/Modules/jaspFrequencies +++ b/Modules/jaspFrequencies @@ -1 +1 @@ -Subproject commit f94529d357d1d7949faadc6b870d0c6a7df8f56d +Subproject commit dbc8094ea7f58e9f9ce4fd3911ccb3844ec19cf4 diff --git a/Modules/jaspJags b/Modules/jaspJags index 6faa88d876..b4fa253a53 160000 --- a/Modules/jaspJags +++ b/Modules/jaspJags @@ -1 +1 @@ -Subproject commit 6faa88d87679764471498c688dd550470fefee81 +Subproject commit b4fa253a53d788d556ecf0352b7f427173b172c5 diff --git a/Modules/jaspLearnBayes b/Modules/jaspLearnBayes index 294d506b48..9822997f54 160000 --- a/Modules/jaspLearnBayes +++ b/Modules/jaspLearnBayes @@ -1 +1 @@ -Subproject commit 294d506b485eed22fa85ff0132be0998335c4f51 +Subproject commit 9822997f54e697755f7cfbb988b81f4a1bdffde9 diff --git a/Modules/jaspLearnStats b/Modules/jaspLearnStats index 301ddd6ff7..6b35d35e6d 160000 --- a/Modules/jaspLearnStats +++ b/Modules/jaspLearnStats @@ -1 +1 @@ -Subproject commit 301ddd6ff77fffbc68324bf00aa5c16cb2b989ca +Subproject commit 6b35d35e6d5a8b59940d390ea83d02141e630f9a diff --git a/Modules/jaspMachineLearning b/Modules/jaspMachineLearning index feff392945..7d4ec8d2bf 160000 --- a/Modules/jaspMachineLearning +++ b/Modules/jaspMachineLearning @@ -1 +1 @@ -Subproject commit feff39294545a1b475910dd59e42fb1af10bda4a +Subproject commit 7d4ec8d2bf8250852a95cb4039f46c7c02b4d4e8 diff --git a/Modules/jaspMetaAnalysis b/Modules/jaspMetaAnalysis index 147a60eac2..7492732479 160000 --- a/Modules/jaspMetaAnalysis +++ b/Modules/jaspMetaAnalysis @@ -1 +1 @@ -Subproject commit 147a60eac2efad430b3279cfb6d2f66de834e6c5 +Subproject commit 7492732479ae9400757d243b02828514e66ca111 diff --git a/Modules/jaspMixedModels b/Modules/jaspMixedModels index e23177a38b..ab81c75c84 160000 --- a/Modules/jaspMixedModels +++ b/Modules/jaspMixedModels @@ -1 +1 @@ -Subproject commit e23177a38b65ddf48d251b02d5e48aa43a00a6a7 +Subproject commit ab81c75c84054de3d6612db99be481729f1237c3 diff --git a/Modules/jaspNetwork b/Modules/jaspNetwork index f9e45cf8cb..4b87044e09 160000 --- a/Modules/jaspNetwork +++ b/Modules/jaspNetwork @@ -1 +1 @@ -Subproject commit f9e45cf8cbec5d2d781d8a86547fc88bd48ebc76 +Subproject commit 4b87044e096e23119f2ed383927f1e96baadd96e diff --git a/Modules/jaspPower b/Modules/jaspPower index fdcfd31800..1c89dee847 160000 --- a/Modules/jaspPower +++ b/Modules/jaspPower @@ -1 +1 @@ -Subproject commit fdcfd31800bafba6bc9b726bfc4591228207a581 +Subproject commit 1c89dee847912df50932e7f15809dd4a2ebd7e26 diff --git a/Modules/jaspPredictiveAnalytics b/Modules/jaspPredictiveAnalytics index 0376f4881a..94c3ee6260 160000 --- a/Modules/jaspPredictiveAnalytics +++ b/Modules/jaspPredictiveAnalytics @@ -1 +1 @@ -Subproject commit 0376f4881a351e4de0373e1104555723e0141b6b +Subproject commit 94c3ee626091d22c39b05cd5d4ebe7b544a1fccc diff --git a/Modules/jaspProcess b/Modules/jaspProcess index 3c2ff78bb8..5177a333f2 160000 --- a/Modules/jaspProcess +++ b/Modules/jaspProcess @@ -1 +1 @@ -Subproject commit 3c2ff78bb8418dc951143bc619a2433bc7ba28a2 +Subproject commit 5177a333f2ad4a39130a6ea7fbfca9d1f33f8b8e diff --git a/Modules/jaspProphet b/Modules/jaspProphet index 8ebdc9819a..3a14d64184 160000 --- a/Modules/jaspProphet +++ b/Modules/jaspProphet @@ -1 +1 @@ -Subproject commit 8ebdc9819a45bd019bf02162ea3b4ed21881d691 +Subproject commit 3a14d64184128870365874d4f229fbd2e0e23538 diff --git a/Modules/jaspQualityControl b/Modules/jaspQualityControl index 266153b5c6..d68c3e2af2 160000 --- a/Modules/jaspQualityControl +++ b/Modules/jaspQualityControl @@ -1 +1 @@ -Subproject commit 266153b5c6fe096d8ae0963eb6e367810c61036b +Subproject commit d68c3e2af232b7a80c8344ed646daef181c1b783 diff --git a/Modules/jaspRegression b/Modules/jaspRegression index abfe57c319..d71789e072 160000 --- a/Modules/jaspRegression +++ b/Modules/jaspRegression @@ -1 +1 @@ -Subproject commit abfe57c3193a23a000fbbcbeca50ebe7778f5c1e +Subproject commit d71789e072759f362ea599ab749ba64e9a2c6cdf diff --git a/Modules/jaspReliability b/Modules/jaspReliability index 29c1eb57d9..754bd00a55 160000 --- a/Modules/jaspReliability +++ b/Modules/jaspReliability @@ -1 +1 @@ -Subproject commit 29c1eb57d9213d4e40a626ddb042caca666e10d1 +Subproject commit 754bd00a551eb189ae4927e364d6ebd1bd12463a diff --git a/Modules/jaspRobustTTests b/Modules/jaspRobustTTests index 162478ce18..52d3f158b4 160000 --- a/Modules/jaspRobustTTests +++ b/Modules/jaspRobustTTests @@ -1 +1 @@ -Subproject commit 162478ce18d909655e3afe2447402cbf8dd675b0 +Subproject commit 52d3f158b43ef7483b101c5501534daad3abf018 diff --git a/Modules/jaspSem b/Modules/jaspSem index 6bdb86f4ec..3cb7948614 160000 --- a/Modules/jaspSem +++ b/Modules/jaspSem @@ -1 +1 @@ -Subproject commit 6bdb86f4ecc75e1aa60c7ef6b603688ff63f7b7f +Subproject commit 3cb7948614516aa5372e060cca3acaef2ef1cef1 diff --git a/Modules/jaspSummaryStatistics b/Modules/jaspSummaryStatistics index 5b92974bff..13ee2dba4a 160000 --- a/Modules/jaspSummaryStatistics +++ b/Modules/jaspSummaryStatistics @@ -1 +1 @@ -Subproject commit 5b92974bff81c1a6654fd0090d92559151e90fbe +Subproject commit 13ee2dba4a8f842c88aa475d482e3f1ca2a0c5ce diff --git a/Modules/jaspSurvival b/Modules/jaspSurvival index 6d1a904c5c..9f77f4ba53 160000 --- a/Modules/jaspSurvival +++ b/Modules/jaspSurvival @@ -1 +1 @@ -Subproject commit 6d1a904c5c376244df7c8ef6c0b545dedbcf2b4b +Subproject commit 9f77f4ba53ba9e431aad6bcfc96112d4af5ccf0a diff --git a/Modules/jaspTTests b/Modules/jaspTTests index e04f30b6db..a6df35440c 160000 --- a/Modules/jaspTTests +++ b/Modules/jaspTTests @@ -1 +1 @@ -Subproject commit e04f30b6db24df245bb46bcb7f7a115c98cc8e02 +Subproject commit a6df35440c6fa45101e7fd69eb7c371b4c499507 diff --git a/Modules/jaspTestModule b/Modules/jaspTestModule index dce9957f60..180a2161ac 160000 --- a/Modules/jaspTestModule +++ b/Modules/jaspTestModule @@ -1 +1 @@ -Subproject commit dce9957f6027f2ba91e1b4cf7c16d0e5a21320b3 +Subproject commit 180a2161aca1002311e51fcad5137e5ed777497c diff --git a/Modules/jaspTimeSeries b/Modules/jaspTimeSeries index e7164bb3f8..76c5bf2618 160000 --- a/Modules/jaspTimeSeries +++ b/Modules/jaspTimeSeries @@ -1 +1 @@ -Subproject commit e7164bb3f8ccfe69f7fedddb6fcac679be40a0fd +Subproject commit 76c5bf2618ee5f712413287c16b094b8b417e663 diff --git a/Modules/jaspVisualModeling b/Modules/jaspVisualModeling index 9573b2d73c..efe6655d42 160000 --- a/Modules/jaspVisualModeling +++ b/Modules/jaspVisualModeling @@ -1 +1 @@ -Subproject commit 9573b2d73c7fee031b3a41f2a55a841b5f67328f +Subproject commit efe6655d42a6e4f1abee5cb82ebc17fbb35c4461 diff --git a/Modules/junctionBootstrap.lock b/Modules/junctionBootstrap.lock new file mode 100644 index 0000000000..3204801b83 --- /dev/null +++ b/Modules/junctionBootstrap.lock @@ -0,0 +1,25 @@ +{ + "R": { + "Version": "4.3.3", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cran.rstudio.com" + } + ] + }, + "Packages": { + "RInside": { + "Package": "RInside", + "Source": "Repository" + }, + "fs": { + "Package": "fs", + "Source": "Repository" + }, + "Rcpp": { + "Package": "Rcpp", + "Source": "Repository" + } + } +} diff --git a/Modules/pkgdepends.lock b/Modules/pkgdepends.lock new file mode 100644 index 0000000000..abe373f5f8 --- /dev/null +++ b/Modules/pkgdepends.lock @@ -0,0 +1,243 @@ +{ + "R": { + "Version": "4.4.1", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cloud.r-project.org" + } + ] + }, + "Packages": { + "R6": { + "Package": "R6", + "Version": "2.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "470851b6d5d0ac559e9d01bb352b4021" + }, + "callr": { + "Package": "callr", + "Version": "3.7.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "processx", + "utils" + ], + "Hash": "9b2191ede20fa29828139b9900922e51" + }, + "cli": { + "Package": "cli", + "Version": "3.6.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "89e6d8219950eac806ae0c489052048a" + }, + "crayon": { + "Package": "crayon", + "Version": "1.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "grDevices", + "methods", + "utils" + ], + "Hash": "e8a1e41acf02548751f45c718d55aa6a" + }, + "curl": { + "Package": "curl", + "Version": "5.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "511bacbfa153a15251166b463b4da4f9" + }, + "desc": { + "Package": "desc", + "Version": "1.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "cli", + "rprojroot", + "utils" + ], + "Hash": "6b9602c7ebbe87101a9c8edb6e8b6d21" + }, + "filelock": { + "Package": "filelock", + "Version": "1.0.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "38ec653c2613bed60052ba3787bd8a2c" + }, + "glue": { + "Package": "glue", + "Version": "1.6.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "1.8.8", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods" + ], + "Hash": "266a20443ca13c65688b2116d5220f76" + }, + "lpSolve": { + "Package": "lpSolve", + "Version": "5.6.20", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "12c7a918599d5700e4265dd8a21f684f" + }, + "pkgbuild": { + "Package": "pkgbuild", + "Version": "1.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "callr", + "cli", + "crayon", + "desc", + "prettyunits", + "processx", + "rprojroot" + ], + "Hash": "beb25b32a957a22a5c301a9e441190b3" + }, + "pkgcache": { + "Package": "pkgcache", + "Version": "2.2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "callr", + "cli", + "curl", + "filelock", + "jsonlite", + "prettyunits", + "processx", + "rappdirs", + "tools", + "utils" + ], + "Hash": "2622106d5651a653c55430ee5f583978" + }, + "pkgdepends": { + "Package": "pkgdepends", + "Version": "0.6.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "callr", + "cli", + "curl", + "desc", + "filelock", + "glue", + "jsonlite", + "lpSolve", + "pkgbuild", + "pkgcache", + "prettyunits", + "processx", + "ps", + "rprojroot", + "stats", + "utils", + "zip" + ], + "Hash": "d0a9c1ca3fbc82d3db84e65f09b42720" + }, + "prettyunits": { + "Package": "prettyunits", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "95ef9167b75dde9d2ccc3c7528393e7e" + }, + "processx": { + "Package": "processx", + "Version": "3.8.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "ps", + "utils" + ], + "Hash": "3efbd8ac1be0296a46c55387aeace0f3" + }, + "ps": { + "Package": "ps", + "Version": "1.7.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "709d852d33178db54b17c722e5b1e594" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "5e3c5dc0b071b21fa128676560dbe94d" + }, + "rprojroot": { + "Package": "rprojroot", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "1de7ab598047a87bba48434ba35d497d" + }, + "zip": { + "Package": "zip", + "Version": "2.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "d98c94dacb7e0efcf83b0a133a705504" + } + } +} diff --git a/Modules/setup_renv_rcpp_rinside.R.in b/Modules/setup_renv_rcpp_rinside.R.in new file mode 100644 index 0000000000..a119bacaa3 --- /dev/null +++ b/Modules/setup_renv_rcpp_rinside.R.in @@ -0,0 +1,79 @@ +# Generated from Tools/setup_renv_rcpp_rinside_jaspModuleInstaller.R.in +# +Sys.setenv(GITHUB_PAT = "@GITHUB_PAT@") +Sys.setenv(RENV_PATHS_ROOT = "@MODULES_RENV_ROOT_PATH@") +Sys.setenv(RENV_PATHS_CACHE = "@MODULES_RENV_CACHE_PATH@") +Sys.setenv(RENV_PATHS_SANDBOX = "@RENV_SANDBOX@") +Sys.setenv(JASPENGINE_LOCATION = "@JASP_ENGINE_PATH@/JASPEngine") + +if("@R_PKG_CELLAR_PATH@" != "") + Sys.setenv(RENV_PATHS_CELLAR = "@R_PKG_CELLAR_PATH@") + +RENV_LIBRARY <- "@RENV_LIBRARY@" +R_CPP_INCLUDES_LIBRARY <- "@R_CPP_INCLUDES_LIBRARY@" +JASPMODULEINSTALLER_LIBRARY <- "@JASPMODULEINSTALLER_LIBRARY@" +PKGDEPENDS_LIBRARY <- "@PKGDEPENDS_LIBRARY@" + +ENGINE <- file.path("@PROJECT_SOURCE_DIR@", "Engine") +MODULES <- file.path("@PROJECT_SOURCE_DIR@", "Modules") +TOOLS <- file.path("@PROJECT_SOURCE_DIR@", "Tools") + +# defines assignFunctionInRenv, getOS, and setupRenv +source(file.path(ENGINE, "jaspModuleInstaller", "R", "renvOverrides.R")) + +mkdir <- function(paths) { + for (path in paths) + if (!dir.exists(path)) + dir.create(path, recursive = TRUE) +} + +mkdir(c(RENV_LIBRARY, R_CPP_INCLUDES_LIBRARY, JASPMODULEINSTALLER_LIBRARY)) + +repos <- "https://packagemanager.posit.co/cran/latest" +# alternative to 'http://cloud.r-project.org' +if (!dir.exists(file.path(RENV_LIBRARY, "renv"))) { + if (@IS_FLATPAK_USED@) { + cat("Installing renv from cellar\n") + install.packages( + pkgs = file.path("@R_PKG_CELLAR_PATH@", "renv.tar.gz"), + lib = RENV_LIBRARY, + INSTALL_opts ='--no-multiarch --no-docs --no-test-load') # --no-test-load is dubious here + } else { + cat("Installing renv from CRAN\n") + install.packages( + pkgs = "renv", + lib = RENV_LIBRARY, + repos ='http://cloud.r-project.org', + INSTALL_opts ='--no-multiarch --no-docs --no-test-load') # --no-test-load is dubious here + } +} else { + cat("renv already installed, not reinstalling\n") +} + +# used by renv +options( + install.opts = "--no-multiarch --no-docs --no-test-load", + # these two could be added to setupRenv + renv.config.install.verbose = TRUE, + renv.config.ppm.default = TRUE +) + +.libPaths(RENV_LIBRARY) +sandboxPaths <- renv:::renv_sandbox_activate() + +#to fix flatpak issue cleaning up on interrupt +if (@IS_FLATPAK_USED@) { + system2(command="chmod", args=c("-R", "777", "@RENV_LIBRARY@/../")) +} + +cat("Using sandbox paths:\n") +for (path in sandboxPaths) + cat(" ", path, "\n", sep = "") + +cat("Restoring Rcpp & RInside\n") +setupRenv(R_CPP_INCLUDES_LIBRARY) +renv::restore( + library = R_CPP_INCLUDES_LIBRARY, + lockfile = file.path(MODULES, "Rcpp_RInside.lock"), + clean = TRUE +) diff --git a/QMLComponents/boundcontrols/boundcontrolcsemtextarea.h b/QMLComponents/boundcontrols/boundcontrolcsemtextarea.h index 2476702760..1209d3aa2c 100644 --- a/QMLComponents/boundcontrols/boundcontrolcsemtextarea.h +++ b/QMLComponents/boundcontrols/boundcontrolcsemtextarea.h @@ -1,12 +1,12 @@ #ifndef BOUNDCONTROLCSEMTEXTAREA_H #define BOUNDCONTROLCSEMTEXTAREA_H -#include "boundcontrollavaantextarea.h" +#include "boundcontrolrlangtextarea.h" -class BoundControlCSemTextArea : public BoundControlLavaanTextArea +class BoundControlCSemTextArea : public BoundControlRlangTextArea { public: - using BoundControlLavaanTextArea::BoundControlLavaanTextArea; + using BoundControlRlangTextArea::BoundControlRlangTextArea; protected: const char * _checkSyntaxRFunctionName() override { return "jaspSem:::checkCSemModel"; } diff --git a/QMLComponents/boundcontrols/boundcontrollavaantextarea.cpp b/QMLComponents/boundcontrols/boundcontrolrlangtextarea.cpp similarity index 86% rename from QMLComponents/boundcontrols/boundcontrollavaantextarea.cpp rename to QMLComponents/boundcontrols/boundcontrolrlangtextarea.cpp index 4de9bdc5ed..ba8a502b3f 100644 --- a/QMLComponents/boundcontrols/boundcontrollavaantextarea.cpp +++ b/QMLComponents/boundcontrols/boundcontrolrlangtextarea.cpp @@ -16,14 +16,14 @@ // . // -#include "boundcontrollavaantextarea.h" +#include "boundcontrolrlangtextarea.h" #include "controls/textareabase.h" #include "log.h" #include "columnencoder.h" #include "analysisform.h" #include -BoundControlLavaanTextArea::BoundControlLavaanTextArea(TextAreaBase *textArea) +BoundControlRlangTextArea::BoundControlRlangTextArea(TextAreaBase *textArea) : BoundControlTextArea(textArea) { @@ -32,14 +32,14 @@ BoundControlLavaanTextArea::BoundControlLavaanTextArea(TextAreaBase *textArea) if (textDocumentQQuick) { QTextDocument* doc = textDocumentQQuick->textDocument(); - _lavaanHighlighter = new LavaanSyntaxHighlighter(doc); + _rLangHighlighter = new RSyntaxHighlighter(doc); //connect(doc, &QTextDocument::contentsChanged, this, &BoundQMLTextArea::contentsChangedHandler); } else Log::log() << "No document object found!" << std::endl; } -void BoundControlLavaanTextArea::bindTo(const Json::Value &value) +void BoundControlRlangTextArea::bindTo(const Json::Value &value) { if (value.type() != Json::objectValue) return; BoundControlBase::bindTo(value); @@ -50,7 +50,7 @@ void BoundControlLavaanTextArea::bindTo(const Json::Value &value) } -Json::Value BoundControlLavaanTextArea::createJson() const +Json::Value BoundControlRlangTextArea::createJson() const { Json::Value result; std::string text = _textArea->text().toStdString(); @@ -62,7 +62,7 @@ Json::Value BoundControlLavaanTextArea::createJson() const return result; } -bool BoundControlLavaanTextArea::isJsonValid(const Json::Value &value) const +bool BoundControlRlangTextArea::isJsonValid(const Json::Value &value) const { if (!value.isObject()) return false; if (!value["modelOriginal"].isString()) return false; @@ -73,7 +73,7 @@ bool BoundControlLavaanTextArea::isJsonValid(const Json::Value &value) const return true; } -void BoundControlLavaanTextArea::checkSyntax() +void BoundControlRlangTextArea::checkSyntax() { QString text = _textArea->text(); @@ -103,7 +103,7 @@ void BoundControlLavaanTextArea::checkSyntax() } -QString BoundControlLavaanTextArea::rScriptDoneHandler(const QString & result) +QString BoundControlRlangTextArea::rScriptDoneHandler(const QString & result) { if (!result.isEmpty()) return result; diff --git a/QMLComponents/boundcontrols/boundcontrollavaantextarea.h b/QMLComponents/boundcontrols/boundcontrolrlangtextarea.h similarity index 78% rename from QMLComponents/boundcontrols/boundcontrollavaantextarea.h rename to QMLComponents/boundcontrols/boundcontrolrlangtextarea.h index bdcc78e79d..07600b2ffe 100644 --- a/QMLComponents/boundcontrols/boundcontrollavaantextarea.h +++ b/QMLComponents/boundcontrols/boundcontrolrlangtextarea.h @@ -16,16 +16,16 @@ // . // -#ifndef BOUNDCONTROLLAVAANTEXTAREA_H -#define BOUNDCONTROLLAVAANTEXTAREA_H +#ifndef BOUNDCONTROLRLANGTEXTAREA_H +#define BOUNDCONTROLRLANGTEXTAREA_H #include "boundcontroltextarea.h" -#include "controls/lavaansyntaxhighlighter.h" +#include "controls/rsyntaxhighlighter.h" -class BoundControlLavaanTextArea : public BoundControlTextArea +class BoundControlRlangTextArea : public BoundControlTextArea { public: - BoundControlLavaanTextArea(TextAreaBase* textArea); + BoundControlRlangTextArea(TextAreaBase* textArea); bool isJsonValid(const Json::Value& optionValue) const override; Json::Value createJson() const override; @@ -35,7 +35,7 @@ class BoundControlLavaanTextArea : public BoundControlTextArea QString rScriptDoneHandler(const QString &result) override; protected: - LavaanSyntaxHighlighter* _lavaanHighlighter = nullptr; + RSyntaxHighlighter* _rLangHighlighter = nullptr; std::set _usedColumnNames; QString _textEncoded; @@ -43,4 +43,4 @@ class BoundControlLavaanTextArea : public BoundControlTextArea }; -#endif // BOUNDCONTROLLAVAANTEXTAREA_H +#endif // BOUNDCONTROLRLANGTEXTAREA_H diff --git a/QMLComponents/components/JASP/Controls/ColorPalette.qml b/QMLComponents/components/JASP/Controls/ColorPalette.qml index 0543232051..841ad4c1d3 100644 --- a/QMLComponents/components/JASP/Controls/ColorPalette.qml +++ b/QMLComponents/components/JASP/Controls/ColorPalette.qml @@ -30,6 +30,7 @@ DropDown { label: qsTr("Colorblind"), value: "colorblind" }, { label: qsTr("Colorblind #2"), value: "colorblind2" }, { label: qsTr("Colorblind #3"), value: "colorblind3" }, + { label: qsTr("JASP"), value: "jaspPalette" }, { label: qsTr("Viridis"), value: "viridis" }, { label: qsTr("ggplot2"), value: "ggplot2" }, { label: qsTr("Gray"), value: "gray" }, diff --git a/QMLComponents/components/JASP/Controls/ComboBox.qml b/QMLComponents/components/JASP/Controls/ComboBox.qml index e6d07c356d..eb213673ae 100644 --- a/QMLComponents/components/JASP/Controls/ComboBox.qml +++ b/QMLComponents/components/JASP/Controls/ComboBox.qml @@ -19,7 +19,7 @@ ComboBoxBase property alias currentLabel: comboBox.currentText property alias value: comboBox.currentValue property alias indexDefaultValue: comboBox.currentIndex - property alias fieldWidth: control.modelWidth + property alias fieldWidth: control.width property bool showVariableTypeIcon: containsVariables property var enabledOptions: [] property bool setLabelAbove: false @@ -28,8 +28,11 @@ ComboBoxBase property bool showBorder: true property bool showEmptyValueAsNormal: false property bool addLineAfterEmptyValue: false + property double controlXOffset: 0 onControlMinWidthChanged: _resetWidth(textMetrics.width) + + function resetWidth(values) { @@ -55,13 +58,16 @@ ComboBoxBase _resetWidth(maxWidth) } - function _resetWidth(maxWidth) + function _resetWidth(maxTextWidth) { - var newWidth = maxWidth + ((comboBox.showVariableTypeIcon ? 20 : 4) * preferencesModel.uiScale); - control.modelWidth = newWidth; - if (control.width < controlMinWidth) - control.modelWidth += (controlMinWidth - control.width); - comboBox.width = comboBox.implicitWidth; // the width is not automatically updated by the implicitWidth... + control.maxTextWidth = maxTextWidth + // The real field width is composed by the type icon (if displayed) + 2-padding + max width + 5-padding + dropdownIcon width + 2-padding + var newFieldWidth = (comboBox.showVariableTypeIcon ? contentIcon.x + contentIcon.width : 0) + maxTextWidth + dropdownIcon.width + 9 * preferencesModel.uiScale + if (newFieldWidth < controlMinWidth) + newFieldWidth = controlMinWidth + + control.realFieldWidth = newFieldWidth + if (!fixedWidth) control.width = newFieldWidth; } Component.onCompleted: control.activated.connect(activated); @@ -85,22 +91,24 @@ ComboBoxBase QTC.ComboBox { - id: control - model: comboBox.model - anchors.left: !rectangleLabel.visible || comboBox.setLabelAbove ? comboBox.left : rectangleLabel.right - anchors.leftMargin: !rectangleLabel.visible || comboBox.setLabelAbove ? 0 : jaspTheme.labelSpacing - anchors.top: rectangleLabel.visible && comboBox.setLabelAbove ? rectangleLabel.bottom: comboBox.top - - focus: true - padding: 2 * preferencesModel.uiScale //jaspTheme.jaspControlPadding - - width: modelWidth + extraWidth - height: jaspTheme.comboBoxHeight - font: jaspTheme.font - property int modelWidth: 30 * preferencesModel.uiScale - property int extraWidth: 5 * padding + dropdownIcon.width - property bool isEmptyValue: comboBox.addEmptyValue && comboBox.currentIndex === 0 + id: control + model: comboBox.model + anchors + { + top: rectangleLabel.visible && comboBox.setLabelAbove ? rectangleLabel.bottom: comboBox.top + left: !rectangleLabel.visible || comboBox.setLabelAbove ? comboBox.left : rectangleLabel.right + leftMargin: controlXOffset + (!rectangleLabel.visible || comboBox.setLabelAbove ? 0 : jaspTheme.labelSpacing) + } + + focus: true + padding: 2 * preferencesModel.uiScale + width: 0 + height: jaspTheme.comboBoxHeight + font: jaspTheme.font + property bool isEmptyValue: comboBox.addEmptyValue && comboBox.currentIndex === 0 property bool showEmptyValueStyle: !comboBox.showEmptyValueAsNormal && isEmptyValue + property double realFieldWidth: width + property double maxTextWidth: 0 TextMetrics { @@ -123,8 +131,8 @@ ComboBoxBase { id: contentIcon height: 15 * preferencesModel.uiScale - width: 15 * preferencesModel.uiScale - x: 3 * preferencesModel.uiScale + width: 15 * preferencesModel.uiScale // Even if not visible, the width should stay the same: if showVariableTypeIcon is true, a value may have no icon, but an empty icon place should still be displayed + x: 2 * preferencesModel.uiScale anchors.verticalCenter: parent.verticalCenter source: !visible ? "" : ((comboBox.currentColumnTypeIcon && comboBox.isBound) ? comboBox.currentColumnTypeIcon : (comboBox.values && comboBox.currentIndex >= 0 && comboBox.currentIndex < comboBox.values.length ? comboBox.values[comboBox.currentIndex].columnTypeIcon : "")) visible: comboBox.showVariableTypeIcon && !control.isEmptyValue && (comboBox.currentColumnType || !comboBox.isBound) @@ -133,19 +141,24 @@ ComboBoxBase Text { anchors.left: contentIcon.visible ? contentIcon.right : parent.left - anchors.leftMargin: 4 * preferencesModel.uiScale + anchors.leftMargin: 2 * preferencesModel.uiScale anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: control.showEmptyValueStyle ? parent.horizontalCenter : undefined text: comboBox.currentText font: control.font color: (!enabled || control.showEmptyValueStyle) ? jaspTheme.grayDarker : jaspTheme.black + width: (fixedWidth ? widthWhenContralHasFixedWidth : control.maxTextWidth) + 5 * preferencesModel.uiScale + elide: Text.ElideRight + + property double widthWhenContralHasFixedWidth: control.width - (x + dropdownIcon.width + 4 * preferencesModel.uiScale) // 4 = leftMargin + 2 padding right of dropdownIcon) + } } indicator: Image { id: dropdownIcon - x: control.width - width - 3 //control.spacing + x: control.width - width - 2 * preferencesModel.uiScale y: control.topPadding + (control.availableHeight - height) / 2 width: 12 * preferencesModel.uiScale height: 12 * preferencesModel.uiScale @@ -180,7 +193,7 @@ ComboBoxBase { id: popupRoot y: control.height - width: comboBoxBackground.width + scrollBar.width + width: Math.max(control.realFieldWidth, fieldWidth) + scrollBar.width property real maxHeight: typeof mainWindowRoot !== 'undefined' ? mainWindowRoot.height // Case Dropdowns used in Desktop : (typeof rcmdRoot !== 'undefined' ? rcmdRoot.height // Case Dropdown used in R Command @@ -211,7 +224,7 @@ ComboBoxBase contentItem: ListView { id: popupView - width: comboBoxBackground.width + width: popupRoot.width - scrollBar.width height: popupRoot.height model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex @@ -239,14 +252,13 @@ ComboBoxBase delegate: QTC.ItemDelegate { height: jaspTheme.comboBoxHeight - implicitWidth: comboBoxBackground.width + width: popupView.width enabled: comboBox.enabledOptions.length == 0 || comboBox.enabledOptions.length <= index || comboBox.enabledOptions[index] contentItem: Rectangle { id: itemRectangle anchors.fill: parent - anchors.rightMargin: scrollBar.visible ? scrollBar.width + 2 : 0 color: comboBox.currentIndex === index ? jaspTheme.itemSelectedColor : (control.highlightedIndex === index ? jaspTheme.itemHoverColor : jaspTheme.controlBackgroundColor) property bool isEmptyValue: comboBox.addEmptyValue && index === 0 diff --git a/QMLComponents/components/JASP/Controls/Form.qml b/QMLComponents/components/JASP/Controls/Form.qml index 36cf1a3b35..b8b0da2d54 100644 --- a/QMLComponents/components/JASP/Controls/Form.qml +++ b/QMLComponents/components/JASP/Controls/Form.qml @@ -240,8 +240,10 @@ AnalysisForm width: parent.width height: visible ? 100 * preferencesModel.uiScale : 0 text: form.rSyntaxText + textType: JASPControl.TextTypeRcode isBound: false onApplyRequest: form.sendRSyntax(text) + autoCheckSyntax: false onInitializedChanged: if (preferencesModel.showRSyntax) control.forceActiveFocus() // If the textarea has already some large text, then it does not display it if it does not get temporarly the focus... } diff --git a/QMLComponents/components/JASP/Controls/GroupBox.qml b/QMLComponents/components/JASP/Controls/GroupBox.qml index 72dc653551..71f44373fd 100644 --- a/QMLComponents/components/JASP/Controls/GroupBox.qml +++ b/QMLComponents/components/JASP/Controls/GroupBox.qml @@ -39,11 +39,11 @@ GroupBoxBase property int columnSpacing: jaspTheme.columnGroupSpacing property int columns: 1 property bool indent: false - property bool alignTextFields: true + property bool alignFields: true property alias label: label property alias preferredWidth: contentArea.width - property var _allTextFields: [] + property var _allAlignableFields: [] property bool _childrenConnected: false Label @@ -90,14 +90,14 @@ GroupBoxBase // The alignment should be done when the scaling of the TextField's are done id: alignTextFieldTimer interval: 50 - onTriggered: _alignTextFields() + onTriggered: _alignFields() } Timer { id: checkFormOverflowAndAlignTimer interval: 50 - onTriggered: _alignTextFields() + onTriggered: _alignFields() } Component.onCompleted: @@ -105,74 +105,74 @@ GroupBoxBase for (var i = 0; i < contentArea.children.length; i++) { var child = contentArea.children[i]; - if (child.hasOwnProperty('controlType') && child.controlType === JASPControl.TextField) - _allTextFields.push(child) + if (child.hasOwnProperty('controlType') && child.hasOwnProperty('controlXOffset'))//child.controlType === JASPControl.TextField) + _allAlignableFields.push(child) } checkFormOverflowAndAlignTimer.start() } - function _alignTextFields() + function _alignFields() { - if (!alignTextFields || _allTextFields.length < 1) return; + if (!alignFields || _allAlignableFields.length < 1) return; - var allTextFieldsPerColumn = {} + var allAlignableFieldsPerColumn = {} var columns = []; - var i, j, textField; + var i, j, field; - for (i = 0; i < _allTextFields.length; i++) + for (i = 0; i < _allAlignableFields.length; i++) { - textField = _allTextFields[i]; + field = _allAlignableFields[i]; if (!_childrenConnected) // Do not connect visible when component is just completed: the visible value is aparently not yet set for all children. // So do it with the first time it is aligned. - textField.visibleChanged.connect(_alignTextFields); + field.visibleChanged.connect(_alignFields); - if (textField.visible) + if (field.visible) { - if (!allTextFieldsPerColumn.hasOwnProperty(textField.x)) + if (!allAlignableFieldsPerColumn.hasOwnProperty(field.x)) { // Cannot use Layout.column to know in which column is the textField. // Then its x value is used. - allTextFieldsPerColumn[textField.x] = [] - columns.push(textField.x) + allAlignableFieldsPerColumn[field.x] = [] + columns.push(field.x) } - allTextFieldsPerColumn[textField.x].push(textField) + allAlignableFieldsPerColumn[field.x].push(field) } } for (i = 0; i < columns.length; i++) { - var textFields = allTextFieldsPerColumn[columns[i]] + var textFields = allAlignableFieldsPerColumn[columns[i]] // To align all the textfields on one column: // . First search for the Textfield with the longest label (its innerControl x position). // . Then add an offset (the controlXOffset) to all other textfields so that they are aligned with the longest TextField if (textFields.length >= 1) { - textField = textFields[0]; - textField.controlXOffset = 0; - var xMax = textField.innerControl.x; - var longestControl = textField.innerControl; + field = textFields[0]; + field.controlXOffset = 0; + var xMax = field.innerControl.x; + var longestControl = field.innerControl; for (j = 1; j < textFields.length; j++) { - textField = textFields[j]; - textField.controlXOffset = 0; - if (xMax < textField.innerControl.x) + field = textFields[j]; + field.controlXOffset = 0; + if (xMax < field.innerControl.x) { - longestControl = textField.innerControl; - xMax = textField.innerControl.x; + longestControl = field.innerControl; + xMax = field.innerControl.x; } } for (j = 0; j < textFields.length; j++) { - textField = textFields[j]; - if (textField.innerControl !== longestControl) + field = textFields[j]; + if (field.innerControl !== longestControl) // Cannot use binding here, since innerControl.x depends on the controlXOffset, // that would generate a binding loop - textField.controlXOffset = (xMax - textField.innerControl.x); + field.controlXOffset = (xMax - field.innerControl.x); } } diff --git a/QMLComponents/components/JASP/Controls/JAGSTextArea.qml b/QMLComponents/components/JASP/Controls/JAGSTextArea.qml index 82693572fe..aa877610ac 100644 --- a/QMLComponents/components/JASP/Controls/JAGSTextArea.qml +++ b/QMLComponents/components/JASP/Controls/JAGSTextArea.qml @@ -5,4 +5,9 @@ import JASP 1.0 TextArea { textType: JASP.TextTypeJAGSmodel + showLineNumber: true + RSyntaxHighlighterQuick + { + textDocument: parent.textDocument + } } diff --git a/QMLComponents/components/JASP/Controls/JASPScrollBar.qml b/QMLComponents/components/JASP/Controls/JASPScrollBar.qml index fb8aefb4d9..b1b99282c3 100644 --- a/QMLComponents/components/JASP/Controls/JASPScrollBar.qml +++ b/QMLComponents/components/JASP/Controls/JASPScrollBar.qml @@ -159,8 +159,8 @@ Item } - onClicked: if(scrollbar.vertical) flickable.contentY = (mouse.y / groove.height * (flickable.contentHeight - flickable.height)) ; - else flickable.contentX = (mouse.x / groove.width * (flickable.contentWidth - flickable.width)) ; + onClicked: (mouse) => { if(scrollbar.vertical) flickable.contentY = (mouse.y / groove.height * (flickable.contentHeight - flickable.height)) ; + else flickable.contentX = (mouse.x / groove.width * (flickable.contentWidth - flickable.width)) ; } } } diff --git a/QMLComponents/components/JASP/Controls/TextArea.qml b/QMLComponents/components/JASP/Controls/TextArea.qml index 81c5118351..944dd37dbb 100644 --- a/QMLComponents/components/JASP/Controls/TextArea.qml +++ b/QMLComponents/components/JASP/Controls/TextArea.qml @@ -29,6 +29,7 @@ TextAreaBase property var undoModel property bool useTabAsSpaces : true property var nextTabItem + property bool showLineNumber : false Component.onCompleted: control.editingFinished.connect(editingFinished) @@ -86,16 +87,62 @@ TextAreaBase boundsBehavior: Flickable.StopAtBounds anchors.fill: parent + Rectangle + { + id: lineNumbersRect + anchors.top: parent.top + anchors.left: parent.left + anchors.topMargin: jaspTheme.contentMargin + anchors.leftMargin: 2 + visible: textArea.showLineNumber + width: lineNumbersRect.visible ? lineNumbers.width : 0 + height: Math.max(flickableRectangle.height, control.contentHeight) + 10 + color: "transparent" + + FontMetrics + { + font: jaspTheme.fontCode + id: lineNumberWidthDeterminer + } + + ListView + { + id: lineNumbers + width: lineNumberWidthDeterminer.advanceWidth(control.lineCount) + jaspTheme.itemPadding + height: parent.height + model: control.lineCount + delegate: Text + { + text: "%1".arg(index + 1) + font: jaspTheme.fontCode + color: jaspTheme.grayDarker + height: control.contentHeight / control.lineCount + anchors.right: parent.right + anchors.rightMargin: jaspTheme.itemPadding / 2 + } + } + + Rectangle + { + id: separator + anchors.top: parent.top + anchors.left: parent.right + width: 2 * preferencesModel.uiScale + height: Math.max(flickableRectangle.height, control.contentHeight) + 10 + color: jaspTheme.borderColor + } + } + QTC.TextArea.flickable: QTC.TextArea { id: control selectByMouse: true selectedTextColor: jaspTheme.white selectionColor: jaspTheme.itemSelectedColor - font: textArea.textType === JASP.TextTypeDefault || textArea.textType === JASP.TextTypeSource ? jaspTheme.font : jaspTheme.fontCode color: textArea.enabled ? jaspTheme.textEnabled : jaspTheme.textDisabled - + leftPadding: !textArea.showLineNumber ? 0 : lineNumbers.width + 2 * jaspTheme.contentMargin + Component.onCompleted: { if (textArea.nextTabItem) diff --git a/QMLComponents/components/JASP/Controls/VariablesForm.qml b/QMLComponents/components/JASP/Controls/VariablesForm.qml index f2e0962129..00c3e0297a 100644 --- a/QMLComponents/components/JASP/Controls/VariablesForm.qml +++ b/QMLComponents/components/JASP/Controls/VariablesForm.qml @@ -49,6 +49,7 @@ VariablesFormBase property bool removeInvisibles : false property double _lastListWidth : 0 + property double _comboBoxHeight : 0 Item { id: items } @@ -153,24 +154,22 @@ VariablesFormBase for (var key in allJASPControls) { var control = allJASPControls[key] - var isControlList = ((control.controlType === JASPControl.VariablesListView) || (control.controlType === JASPControl.FactorLevelList) || (control.controlType === JASPControl.InputListView)) if (removeInvisibles && !control.visible) - control.height = 0 + control.anchors.top = variablesForm.top; else { control.anchors.top = anchorTop; control.anchors.topMargin = firstControl ? 0 : marginBetweenVariablesLists; anchorTop = control.bottom; - if (removeInvisibles && control.visible && control.height == 0) // Reset the height of the control when it bocomes visible again - control.height = control.maxRows === 1 ? jaspTheme.defaultSingleItemListHeight : jaspTheme.defaultVariablesFormHeight - if (!firstControl) minHeightOfAssignedControls += marginBetweenVariablesLists; firstControl = false; + var isControlList = ((control.controlType === JASPControl.VariablesListView) || (control.controlType === JASPControl.FactorLevelList) || (control.controlType === JASPControl.InputListView)) + if (!isControlList) minHeightOfAssignedControls += control.height; else if (control.maxRows === 1 || !heightSetByForm(control)) @@ -186,7 +185,7 @@ VariablesFormBase } } } - + // Set the height of controls (that have not singleVariable set or where the height is already specifically set) // so that the AssignedVariablesList column is as long as the AvailableVariablesList column. if (changeableHeightControls.length > 0) diff --git a/QMLComponents/controls/comboboxbase.cpp b/QMLComponents/controls/comboboxbase.cpp index da42b9c959..4bfa3bcca7 100644 --- a/QMLComponents/controls/comboboxbase.cpp +++ b/QMLComponents/controls/comboboxbase.cpp @@ -118,6 +118,9 @@ bool ComboBoxBase::isJsonValid(const Json::Value &optionValue) const void ComboBoxBase::setUp() { + if (property("fieldWidth").toInt() > 0) // If the fieldWidth is set, it means the width should be fixed and not dependent on the values of the dropdown. + _fixedWidth = true; + JASPListControl::setUp(); _model->resetTermsFromSources(); diff --git a/QMLComponents/controls/comboboxbase.h b/QMLComponents/controls/comboboxbase.h index d70d232c29..9ee4ea82d6 100644 --- a/QMLComponents/controls/comboboxbase.h +++ b/QMLComponents/controls/comboboxbase.h @@ -35,6 +35,8 @@ class ComboBoxBase : public JASPListControl, public BoundControlBase Q_PROPERTY( QString startValue READ startValue WRITE setStartValue NOTIFY startValueChanged ) Q_PROPERTY( QString currentColumnType READ currentColumnType NOTIFY currentColumnTypeChanged ) Q_PROPERTY( QString currentColumnTypeIcon READ currentColumnTypeIcon NOTIFY currentColumnTypeIconChanged ) + Q_PROPERTY( bool fixedWidth READ fixedWidth NOTIFY fixedWidthChanged ) + public: ComboBoxBase(QQuickItem* parent = nullptr); @@ -53,6 +55,7 @@ class ComboBoxBase : public JASPListControl, public BoundControlBase const QString& currentColumnType() const { return _currentColumnType; } const QString& currentColumnTypeIcon() const { return _currentColumnTypeIcon;} int currentIndex() const { return _currentIndex; } + bool fixedWidth() const { return _fixedWidth; } std::vector usedVariables() const override; @@ -65,6 +68,7 @@ class ComboBoxBase : public JASPListControl, public BoundControlBase void currentColumnTypeIconChanged(); void currentIndexChanged(); void activated(int index); + void fixedWidthChanged(); protected slots: void termsChangedHandler() override; @@ -84,6 +88,7 @@ protected slots: _currentColumnRealType, _currentColumnTypeIcon; int _currentIndex = -1; + bool _fixedWidth = false; int _getStartIndex() const; void _resetItemWidth(); diff --git a/QMLComponents/controls/lavaansyntaxhighlighter.cpp b/QMLComponents/controls/lavaansyntaxhighlighter.cpp deleted file mode 100644 index cc0424a5f1..0000000000 --- a/QMLComponents/controls/lavaansyntaxhighlighter.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (C) 2013-2018 University of Amsterdam -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public -// License along with this program. If not, see -// . -// - -#include "lavaansyntaxhighlighter.h" - -LavaanSyntaxHighlighter::LavaanSyntaxHighlighter(QTextDocument *parent) - : QSyntaxHighlighter(parent) -{ - - HighlightingRule rule; - - // operators - operatorFormat.setForeground(Qt::darkGreen); - QStringList operatorPatterns; - operatorPatterns << "\\=" << "\\~" << "\\<" - << "\\*" << "\\>" << "\\:" - << "\\%" << "\\|" << "\\+"; - for (const QString &pattern : operatorPatterns) { - rule.pattern = QRegularExpression(pattern); - rule.format = operatorFormat; - highlightingRules.append(rule); - } - - // variables - variableFormat.setToolTip("variable"); - rule.pattern = QRegularExpression("\\b\\w*\\b"); - rule.format = variableFormat; - highlightingRules.append(rule); - - // comments - commentFormat.setForeground(Qt::darkGray); - commentFormat.setFontItalic(true); - rule.pattern = QRegularExpression("#[^\n]*"); - rule.format = commentFormat; - highlightingRules.append(rule); -} - -void LavaanSyntaxHighlighter::highlightBlock(const QString &text) -{ - for (const HighlightingRule &rule : highlightingRules) - { - QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); - while (matchIterator.hasNext()) - { - QRegularExpressionMatch match = matchIterator.next(); - setFormat(match.capturedStart(), match.capturedLength(), rule.format); - } - } -} diff --git a/QMLComponents/controls/lavaansyntaxhighlighter.h b/QMLComponents/controls/lavaansyntaxhighlighter.h deleted file mode 100644 index badfcb1b9e..0000000000 --- a/QMLComponents/controls/lavaansyntaxhighlighter.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (C) 2013-2018 University of Amsterdam -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public -// License along with this program. If not, see -// . -// - -#ifndef LAVAANSYNTAXHIGHLIGHTER_H -#define LAVAANSYNTAXHIGHLIGHTER_H - -#include -#include -#include - -class LavaanSyntaxHighlighter : public QSyntaxHighlighter -{ -public: - LavaanSyntaxHighlighter(QTextDocument *parent); - virtual void highlightBlock(const QString &text) override; -private: - struct HighlightingRule - { - QRegularExpression pattern; - QTextCharFormat format; - }; - QVector highlightingRules; - QTextCharFormat operatorFormat; - QTextCharFormat variableFormat; - QTextCharFormat commentFormat; -}; - -#endif // LAVAANSYNTAXHIGHLIGHTER_H diff --git a/QMLComponents/controls/rsyntaxhighlighter.cpp b/QMLComponents/controls/rsyntaxhighlighter.cpp new file mode 100644 index 0000000000..d09472d7f0 --- /dev/null +++ b/QMLComponents/controls/rsyntaxhighlighter.cpp @@ -0,0 +1,144 @@ +// +// Copyright (C) 2013-2018 University of Amsterdam +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public +// License along with this program. If not, see +// . +// + +#include "rsyntaxhighlighter.h" + +RSyntaxHighlighter::RSyntaxHighlighter(QTextDocument *parent) + : QSyntaxHighlighter(parent), VariableInfoConsumer(), _textDocument(parent) +{ + if(VariableInfo::info()) + { + connect(VariableInfo::info(), &VariableInfo::namesChanged, this, &RSyntaxHighlighter::handleNamesChanged); + connect(VariableInfo::info(), &VariableInfo::rowCountChanged, this, &RSyntaxHighlighter::handleRowCountChanged); + } + + HighlightingRule rule; + // most of these R regExp are copied from: https://github.com/PrismJS/prism/blob/master/components/prism-r.js + + // operators + _operatorFormat.setForeground(Qt::red); + rule.pattern = QRegularExpression(R"(->?>?|<(?:=|=!]=?|::?|&&?|\|\|?|[+*\/^$@~]|%[^%\s]*%)"); + rule.format = _operatorFormat; + _highlightingRules.append(rule); + + // variables + _variableFormat.setToolTip("variable"); + rule.pattern = QRegularExpression(R"(\b\w*\b)"); + rule.format = _variableFormat; + _highlightingRules.append(rule); + + // string + _stringFormat.setForeground(Qt::darkGreen); + rule.pattern = QRegularExpression(R"(([`'"])(?:\\.|(?!\1)[^\\\r\n])*\1)"); + rule.format = _stringFormat; + _highlightingRules.append(rule); + + // keyword + _keywordFormat.setForeground(Qt::darkCyan); + rule.pattern = QRegularExpression(R"(\b(?:NA|NA_character_|NA_complex_|NA_integer_|NA_real_|NULL|break|else|for|function|if|in|next|repeat|while)\b)"); + rule.format = _keywordFormat; + _highlightingRules.append(rule); + + // boolean and special number + _booleanFormat.setForeground(Qt::magenta); + rule.pattern = QRegularExpression(R"(\b(?:FALSE|TRUE|Inf|NaN)\b)"); + rule.format = _booleanFormat; + _highlightingRules.append(rule); + + // number + _numberFormat.setForeground(Qt::darkMagenta); + rule.pattern = QRegularExpression(R"((?:\b0x[\dA-Fa-f]+(?:\.\d*)?|\b\d+(?:\.\d*)?|\B\.\d+)(?:[EePp][+-]?\d+)?[iL]?)"); + rule.format = _numberFormat; + _highlightingRules.append(rule); + + // punctuation + _punctuationFormat.setForeground(Qt::blue); + rule.pattern = QRegularExpression(R"([(){}\[\],;])"); + rule.format = _punctuationFormat; + _highlightingRules.append(rule); + + // comments + _commentFormat.setForeground(Qt::darkGray); + _commentFormat.setFontItalic(true); + _commentRule.pattern = QRegularExpression(R"(#[^\n]*)"); + _commentRule.format = _commentFormat; + + // columns + _columnFormat.setForeground(Qt::blue); + _columnFormat.setFontItalic(true); +} + +void RSyntaxHighlighter::highlightBlock(const QString &text) +{ + setStringsFormat(text, '"'); + setStringsFormat(text, '\''); + setStringsFormat(text, '`'); + + for (const HighlightingRule & rule : _highlightingRules) + applyRule(text, rule); + + //Do columns + QStringList names = requestInfo(VariableInfo::InfoType::VariableNames).toStringList(); + + for(const QString & name : names) + applyRule(text, QRegularExpression(QString(R"(%1)").arg(name)), _columnFormat); + + applyRule(text, _commentRule); +} + +void RSyntaxHighlighter::setStringsFormat(const QString &text, QChar c) +{ + int start = -1; + for (int i = 0; i < text.size(); ++i) + { + if (text[i] == c && (i == 0 || text[i - 1] != '\\')) + { + if (start == -1) + start = i; + else + { + setFormat(start, i - start + 1, _stringFormat); + start = -1; + } + } + } +} + +void RSyntaxHighlighter::applyRule(const QString & text, const QRegularExpression & pattern, const QTextCharFormat & format) +{ + QRegularExpressionMatchIterator matchIterator = pattern.globalMatch(text); + + while (matchIterator.hasNext()) + { + QRegularExpressionMatch match = matchIterator.next(); + setFormat(match.capturedStart(), match.capturedLength(), format); + } +} + +void RSyntaxHighlighterQuick::setTextDocument(QQuickTextDocument *textDocument) +{ + if(_textDocument == textDocument) + return; + + _textDocument = textDocument; + + if(_textDocument) + _highlighter = new RSyntaxHighlighter(_textDocument->textDocument()); + + emit textDocumentChanged(); +} diff --git a/QMLComponents/controls/rsyntaxhighlighter.h b/QMLComponents/controls/rsyntaxhighlighter.h new file mode 100644 index 0000000000..0bfe8f1fd2 --- /dev/null +++ b/QMLComponents/controls/rsyntaxhighlighter.h @@ -0,0 +1,92 @@ +// +// Copyright (C) 2013-2018 University of Amsterdam +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public +// License along with this program. If not, see +// . +// + +#ifndef RLANGSYNTAXHIGHLIGHTER_H +#define RLANGSYNTAXHIGHLIGHTER_H + +#include +#include +#include +#include +#include +#include "variableinfo.h" + +class RSyntaxHighlighter : public QSyntaxHighlighter, public VariableInfoConsumer +{ + Q_OBJECT + + struct HighlightingRule + { + QRegularExpression pattern; + QTextCharFormat format; + }; + +public: + RSyntaxHighlighter(QTextDocument *parent); + + void highlightBlock(const QString &text) override; + void setStringsFormat(const QString &text, QChar c); + + void applyRule(const QString & text, const HighlightingRule & rule) { applyRule(text, rule.pattern, rule.format); } + void applyRule(const QString & text, const QRegularExpression & pattern, const QTextCharFormat & format); + + + +protected slots: + void handleNamesChanged(QMap changedNames) { rehighlight(); } + void handleRowCountChanged() { rehighlight(); } + +private: + + + QTextDocument * _textDocument = nullptr; + + QVector _highlightingRules; + QTextCharFormat _punctuationFormat, + _operatorFormat, + _variableFormat, + _commentFormat, + _keywordFormat, + _stringFormat, + _booleanFormat, + _numberFormat, + _columnFormat; + HighlightingRule _commentRule; +}; + +class RSyntaxHighlighterQuick : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QQuickTextDocument* textDocument READ textDocument WRITE setTextDocument NOTIFY textDocumentChanged) + +public: + RSyntaxHighlighterQuick(QQuickItem * parent = nullptr) : QQuickItem(parent) {} + + QQuickTextDocument * textDocument() { return _textDocument; } + + void setTextDocument(QQuickTextDocument * textDocument); + +signals: + void textDocumentChanged(); + +private: + RSyntaxHighlighter * _highlighter = nullptr; + QQuickTextDocument * _textDocument = nullptr; +}; + +#endif // RLANGSYNTAXHIGHLIGHTER_H diff --git a/QMLComponents/controls/textareabase.cpp b/QMLComponents/controls/textareabase.cpp index 3394c08ae5..9e031eafc5 100644 --- a/QMLComponents/controls/textareabase.cpp +++ b/QMLComponents/controls/textareabase.cpp @@ -20,7 +20,7 @@ #include "analysisform.h" #include "boundcontrols/boundcontrolsourcetextarea.h" #include "boundcontrols/boundcontroljagstextarea.h" -#include "boundcontrols/boundcontrollavaantextarea.h" +#include "boundcontrols/boundcontrolrlangtextarea.h" #include "boundcontrols/boundcontrolcsemtextarea.h" @@ -53,7 +53,8 @@ void TextAreaBase::setUp() switch (_textType) { case TextType::TextTypeSource: _boundControl = new BoundControlSourceTextArea(this); break; - case TextType::TextTypeLavaan: _boundControl = new BoundControlLavaanTextArea(this); break; + case TextType::TextTypeLavaan: _boundControl = new BoundControlRlangTextArea(this); break; + case TextType::TextTypeRcode: _boundControl = new BoundControlRlangTextArea(this); break; case TextType::TextTypeJAGSmodel: _boundControl = new BoundControlJAGSTextArea(this); break; case TextType::TextTypeCSem: _boundControl = new BoundControlCSemTextArea(this); break; default: _boundControl = new BoundControlTextArea(this); break; @@ -72,7 +73,7 @@ void TextAreaBase::setUp() //If "rowCount" changes on VariableInfo it means a column has been added or removed, this means the model should be reencoded and checked //Fixes https://github.com/jasp-stats/jasp-issues/issues/2462 - connect(VariableInfo::info(), &VariableInfo::rowCountChanged, this, &TextAreaBase::checkSyntaxHandler); + connect(VariableInfo::info(), &VariableInfo::rowCountChanged, this, &TextAreaBase::checkSyntaxMaybeHandler); //Also do it on request of course ;) connect(this, &TextAreaBase::applyRequest, this, &TextAreaBase::checkSyntaxHandler); @@ -123,3 +124,16 @@ void TextAreaBase::_setInitialized(const Json::Value &value) if (keepText) setText(currentText); } + +bool TextAreaBase::autoCheckSyntax() const +{ + return _autoCheckSyntax; +} + +void TextAreaBase::setAutoCheckSyntax(bool newAutoCheckSyntax) +{ + if (_autoCheckSyntax == newAutoCheckSyntax) + return; + _autoCheckSyntax = newAutoCheckSyntax; + emit autoCheckSyntaxChanged(); +} diff --git a/QMLComponents/controls/textareabase.h b/QMLComponents/controls/textareabase.h index 7c71f79a9f..cf3534fdbf 100644 --- a/QMLComponents/controls/textareabase.h +++ b/QMLComponents/controls/textareabase.h @@ -38,6 +38,7 @@ class TextAreaBase : public JASPListControl, public BoundControl Q_PROPERTY( TextType textType READ textType WRITE setTextType NOTIFY textTypeChanged ) Q_PROPERTY( bool hasScriptError READ hasScriptError WRITE setHasScriptError NOTIFY hasScriptErrorChanged ) + Q_PROPERTY( bool autoCheckSyntax READ autoCheckSyntax WRITE setAutoCheckSyntax NOTIFY autoCheckSyntaxChanged ) public: TextAreaBase(QQuickItem* parent = nullptr); @@ -66,11 +67,15 @@ class TextAreaBase : public JASPListControl, public BoundControl QString text(); void setText(const QString& text); + bool autoCheckSyntax() const; + void setAutoCheckSyntax(bool newAutoCheckSyntax); + public slots: GENERIC_SET_FUNCTION(TextType, _textType, textTypeChanged, TextType ) GENERIC_SET_FUNCTION(HasScriptError, _hasScriptError, hasScriptErrorChanged, bool ) - void checkSyntaxHandler() { _boundControl->checkSyntax(); } + void checkSyntaxHandler() { _boundControl->checkSyntax(); } + void checkSyntaxMaybeHandler() { if(_autoCheckSyntax) checkSyntaxHandler(); } signals: void textTypeChanged(); @@ -78,6 +83,8 @@ public slots: void applyRequest(); void editingFinished(); + void autoCheckSyntaxChanged(); + protected slots: void termsChangedHandler() override; @@ -86,11 +93,11 @@ protected slots: BoundControlTextArea* _boundControl = nullptr; TextType _textType = TextType::TextTypeDefault; - bool _hasScriptError = false; + bool _hasScriptError = false, + _autoCheckSyntax = true; QList _separators; ListModelTermsAvailable* _model = nullptr; - }; diff --git a/R-Interface/CMakeLists.txt b/R-Interface/CMakeLists.txt index 8807e597fa..de3bb51c17 100644 --- a/R-Interface/CMakeLists.txt +++ b/R-Interface/CMakeLists.txt @@ -91,9 +91,17 @@ if(WIN32) set(R_EXECUTABLE "${R_HOME_PATH}/bin/R") set(R_INCLUDE_PATH "${R_HOME_PATH}/include") - set(RCPP_PATH "${R_LIBRARY_PATH}/Rcpp") - set(RINSIDE_PATH "${R_LIBRARY_PATH}/RInside") - set(RENV_PATH "${R_LIBRARY_PATH}/renv") + set(RENV_PATH "${JASP_BINARY_DIR}/_cache/R/renv_library/renv") + + set(R_CPP_INCLUDES_LIBRARY "${JASP_BINARY_DIR}/Modules/Tools/R_cpp_includes_library") + include(FindRPackagePath) + + find_package_path(RCPP_PATH ${R_CPP_INCLUDES_LIBRARY} "Rcpp") + find_package_path(RINSIDE_PATH ${R_CPP_INCLUDES_LIBRARY} "RInside") + + message(STATUS "RCPP_PATH = ${RCPP_PATH}") + message(STATUS "RINSIDE_PATH = ${RINSIDE_PATH}") + message(STATUS "RENV_PATH = ${RENV_PATH}") include(FetchContent) include(ExternalProject) diff --git a/R-Interface/R/symlinkTools.R b/R-Interface/R/symlinkTools.R index a4f62b883c..116939faf7 100644 --- a/R-Interface/R/symlinkTools.R +++ b/R-Interface/R/symlinkTools.R @@ -42,8 +42,8 @@ determineOverlap <- function(targetRoot, sourceRoot) { targetSplit <- splitPath(target) rootToSrc <- pastePath(sourceSplit[seq(overlap$len + 1, length(sourceSplit))]) - stepsDown <- length(targetSplit) - (overlap$len + as.integer(addRootToSource)) - tgtToSrc <- pastePath(rep("..", stepsDown) ) + stepsDown <- length(targetSplit) - (overlap$len + as.integer(addRootToSource)) - 1 + tgtToSrc <- pastePath(rep("..", max(0, stepsDown)) ) #for debug: #tgtToSrc <- paste0(tgtToSrc, .Platform$file.sep, ".") @@ -70,7 +70,7 @@ getRelativityFunction <- function(modulesRoot, renvCache) { if (Sys.info()["sysname"] == "Darwin") { - modToRenvS <- pastePath(c("..", "renv-cache")) + modToRenvS <- "renv-cache" } else { modToRenvF <- determineOverlap(modulesRoot, renvCache) modToRenvS <- modToRenvF$targetToSource(renvCache, TRUE) @@ -85,7 +85,11 @@ getRelativityFunction <- function(modulesRoot, renvCache) pathToRenv <- determineOverlap(targetPath, renvCache)$sourceToTarget linkToModS <- linkToMod(linkLocation, FALSE) - linkToRenvS <- modToRenvS #pastePath(c(linkToModS, modToRenvS)) + if (Sys.info()["sysname"] == "Darwin") { + linkToRenvS <- pastePath(c(linkToModS, modToRenvS)) + } else { + linkToRenvS <- modToRenvS + } pathToRenvS <- pathToRenv(targetPath) newTarget <- paste0(linkToRenvS, .Platform$file.sep, pathToRenvS) @@ -160,7 +164,7 @@ collectLinks <- function(modulesRoot, renvCache, isLink, getLink) if(!startsWith(symPath, ".")) #if starts with dot it is already relative symlinks[nrow(symlinks)+1, ] <<- list(linkLocation=path, linkTarget=relativeer(path, symPath), originalTarget=symPath) } - else if (depth < 2) + else if (depth < 6) { everything <- list.files(path, recursive=FALSE, include.dirs=TRUE, all.files=FALSE, full.names=TRUE) @@ -247,8 +251,8 @@ collectAndStoreJunctions <- function(buildfolder) symlinks <- collectLinks(modulesRoot, renvCache, isJunction2, normalizePath) overlap <- determineOverlap(modulesRoot, modulesRoot) relLink <- lapply(symlinks$linkLocation, overlap$sourceToTarget) - modules <- lapply(relLink, function(p) splitPath(p)[[1]]) - links <- lapply(relLink, function(p) splitPath(p)[[2]]) + modules <- lapply(relLink, function(p) { x <- splitPath(p); pastePath(head(x, n=-1)) }) + links <- lapply(relLink, function(p) { x <- splitPath(p); tail(x, n=1) }) if(nrow(symlinks) == 0) print("No absolute symlinks found, maybe you ran this script already?") @@ -261,6 +265,10 @@ collectAndStoreJunctions <- function(buildfolder) restoreJunctions <- function(modulesFolder, junctionsFolder, junctionRDSPath) { + #copy all the non junction dependencies into the Tools + require(utils) + file.copy(utils::shortPathName(pastePath(c(modulesFolder, "Tools"))), shortPathName(junctionsFolder), recursive = TRUE, overwrite = FALSE) + # Should contain a data.frame with columns: renv, module and link. # As created in collectAndStoreJunctions junctions <- readRDS(junctionRDSPath) @@ -281,7 +289,7 @@ restoreJunctions <- function(modulesFolder, junctionsFolder, junctionRDSPath) modDir <- pastePath(c(junctionsFolder, module)) if(!file.exists(modDir)) - dir.create(modDir) + dir.create(modDir, recursive = TRUE) setwd(modDir) # print(paste0("Creating junction '", padToMax(link, 1), "' to '", padToMax(renv, 2), "' in '", padToMax(pastePath(c(modulesRoot, module)), 3), "'")) diff --git a/R-Interface/jasprcpp.cpp b/R-Interface/jasprcpp.cpp index 62f31e10d8..de78232b64 100644 --- a/R-Interface/jasprcpp.cpp +++ b/R-Interface/jasprcpp.cpp @@ -56,6 +56,7 @@ getColNames getAllColumnNames; static logFlushDef _logFlushFunction = nullptr; static logWriteDef _logWriteFunction = nullptr; static sendFuncDef _sendToDesktop = nullptr; +static pollMessagesFuncDef _pollMessagesFunction = nullptr; static systemDef _systemFunc = nullptr; static libraryFixerDef _libraryFixerFunc = nullptr; static std::string _R_HOME = ""; @@ -75,13 +76,13 @@ void STDCALL jaspRCPP_init(const char* buildYear, const char* version, RBridgeCa _logFlushFunction = logFlushFunction; _logWriteFunction = logWriteFunction; _sendToDesktop = sendToDesktopFunction; + _pollMessagesFunction = pollMessagesFunction; _systemFunc = systemFunc; _libraryFixerFunc = libraryFixerFunc; jaspRCPP_logString("Creating RInside.\n"); rinside = new RInside(); - R_TempDir = (char*)tempDir; RInside &rInside = rinside->instance(); @@ -152,12 +153,36 @@ void STDCALL jaspRCPP_init(const char* buildYear, const char* version, RBridgeCa Rcpp::RObject sinkObj = rInside[".outputSink"]; //jaspRCPP_logString(sinkObj.isNULL() ? "sink is null\n" : !sinkObj.isObject() ? " sink is not object\n" : sinkObj.isS4() ? "sink is s4\n" : "sink is obj but not s4\n"); + rInside.parseEvalQNT("sink(.outputSink); print(.libPaths()); sink();"); + + // initialize everything unrelated to jaspBase static const char *baseCitationFormat = "JASP Team (%s). JASP (Version %s) [Computer software]."; char baseCitation[200]; snprintf(baseCitation, 200, baseCitationFormat, buildYear, version); rInside[".baseCitation"] = baseCitation; rInside[".jaspVersion"] = version; + rInside[".baseCitation"] = baseCitation; + rInside[".numDecimals"] = 3; + rInside[".fixedDecimals"] = false; + rInside[".normalizedNotation"] = true; + rInside[".exactPValues"] = false; + rInside[".resultFont"] = "Arial"; + rInside[".imageBackground"] = "transparent"; + rInside[".ppi"] = 300; + + jaspRCPP_parseEvalQNT("library(methods)"); + + _R_HOME = jaspRCPP_parseEvalStringReturn("R.home('')"); + jaspRCPP_logString("R_HOME is: " + _R_HOME + "\n"); + +} + +void STDCALL jaspRCPP_init_jaspBase() +{ + + jaspRCPP_logString("Start initializing jaspBase\n"); + //XPtr doesnt like it if it can't run a finalizer so here are some dummy variables: static logFuncDef _logFuncDef = jaspRCPP_logString; static getColumnTypeFuncDef _getColumnTypeFuncDef = jaspRCPP_getColumnType; @@ -174,14 +199,17 @@ void STDCALL jaspRCPP_init(const char* buildYear, const char* version, RBridgeCa static enDecodeFuncDef _encodeColumnName = jaspRCPP_encodeColumnName; static enDecodeFuncDef _decodeColumnName = jaspRCPP_decodeColumnName; + RInside &rInside = rinside->instance(); + rInside[".logString"] = Rcpp::XPtr( & _logFuncDef); rInside[".createColumn"] = Rcpp::XPtr( & _createColumnFuncDef); rInside[".deleteColumn"] = Rcpp::XPtr( & _deleteColumnFuncDef); rInside[".getColumnType"] = Rcpp::XPtr( & _getColumnTypeFuncDef); rInside[".getColumnExists"] = Rcpp::XPtr( & _getColumnExistsFuncDef); rInside[".getColumnAnalysisId"] = Rcpp::XPtr( & _getColumnAnIdFuncDef); - rInside[".sendToDesktopFunction"] = Rcpp::XPtr( & sendToDesktopFunction); - rInside[".pollMessagesFunction"] = Rcpp::XPtr( & pollMessagesFunction); + rInside[".sendToDesktopFunction"] = Rcpp::XPtr( & _sendToDesktop); + rInside[".pollMessagesFunction"] = Rcpp::XPtr( & _pollMessagesFunction); + rInside[".setColumnDataAsScalePtr"] = Rcpp::XPtr( & _setColumnDataAsScale); rInside[".setColumnDataAsOrdinalPtr"] = Rcpp::XPtr( & _setColumnDataAsOrdinal); rInside[".setColumnDataAsNominalPtr"] = Rcpp::XPtr( & _setColumnDataAsOrdinal); @@ -189,17 +217,6 @@ void STDCALL jaspRCPP_init(const char* buildYear, const char* version, RBridgeCa rInside[".shouldDecodeColName"] = Rcpp::XPtr(& _shouldDecodeColumnName); rInside[".encodeColName"] = Rcpp::XPtr( & _encodeColumnName); rInside[".decodeColName"] = Rcpp::XPtr( & _decodeColumnName); - rInside[".baseCitation"] = baseCitation; - rInside[".numDecimals"] = 3; - rInside[".fixedDecimals"] = false; - rInside[".normalizedNotation"] = true; - rInside[".exactPValues"] = false; - rInside[".resultFont"] = "Arial"; - rInside[".imageBackground"] = "transparent"; - rInside[".ppi"] = 300; - - - //jaspRCPP_parseEvalQNT("options(encoding = 'UTF-8')"); //Pass a whole bunch of pointers to jaspBase jaspRCPP_parseEvalQNT("jaspBase:::setColumnFuncs( .setColumnDataAsScalePtr, .setColumnDataAsOrdinalPtr, .setColumnDataAsNominalPtr, .getColumnType, .getColumnAnalysisId, .createColumn, .deleteColumn, .getColumnExists, .encodeColName, .decodeColName, .shouldEncodeColName, .shouldDecodeColName)"); @@ -208,21 +225,21 @@ void STDCALL jaspRCPP_init(const char* buildYear, const char* version, RBridgeCa jaspRCPP_parseEvalQNT("jaspBase:::setPollMessagesFunc( .pollMessagesFunction)"); jaspRCPP_parseEvalQNT("jaspBase:::setBaseCitation( .baseCitation)"); jaspRCPP_parseEvalQNT("jaspBase:::setInsideJasp()"); + jaspRCPP_parseEvalQNT("jaspBase:::registerFonts()"); //Load it jaspRCPP_logString("Initializing jaspBase.\n"); - jaspRCPP_parseEvalQNT("library(methods)"); jaspRCPP_parseEvalQNT("library(jaspBase)"); // if we have a separate engine for each module then we should move these kind of hacks to the .onAttach() of each module (instead of loading BayesFactor when Descriptives is requested). // jaspRCPP_logString("initEnvironment().\n"); // jaspRCPP_parseEvalQNT("initEnvironment()"); - _R_HOME = jaspRCPP_parseEvalStringReturn("R.home('')"); - jaspRCPP_logString("R_HOME is: " + _R_HOME + "\n"); - jaspRCPP_logString("initializeDoNotRemoveList().\n"); jaspRCPP_parseEvalQNT("jaspBase:::.initializeDoNotRemoveList()"); + + jaspRCPP_logString("Finished initializing jaspBase.\n"); + } void STDCALL jaspRCPP_junctionHelper(bool collectNotRestore, const char * modulesFolder, const char * linkFolder, const char * junctionsFilePath) @@ -232,10 +249,11 @@ void STDCALL jaspRCPP_junctionHelper(bool collectNotRestore, const char * module std::cout << "RInside created, now about to " << (collectNotRestore ? "collect" : "recreate") << " Modules junctions in renv-cache" << std::endl; - rinside->parseEvalQNT("source('Modules/symlinkTools.R')"); + rinside->parseEvalQNT("source('Modules/Tools/symlinkTools.R')"); rInside["modulesFolder"] = modulesFolder; rInside["symFolder"] = linkFolder; rInside["junctionsFilePath"] = junctionsFilePath; + rinside->parseEvalQNT(".libPaths( c( paste0( modulesFolder, 'Tools/junction_bootstrap_library' ) , .libPaths() ) )"); if(collectNotRestore) rinside->parseEvalQNT("collectAndStoreJunctions(modulesFolder)"); else rinside->parseEvalQNT("restoreModulesIfNeeded( modulesFolder, symFolder, junctionsFilePath)"); @@ -285,7 +303,8 @@ void STDCALL jaspRCPP_setFontAndPlotSettings(const char * resultFont, const int rInside[".imageBackground"] = imageBackground; rInside[".ppi"] = ppi; - jaspRCPP_parseEvalQNT("jaspBase:::registerFonts()"); + // sometimes jaspBase is not available + jaspRCPP_parseEvalQNT("try(jaspBase:::registerFonts())"); } const char* STDCALL jaspRCPP_runModuleCall(const char* name, const char* title, const char* moduleCall, const char* dataKey, const char* options, diff --git a/R-Interface/jasprcpp_interface.h b/R-Interface/jasprcpp_interface.h index d8004a8954..4d0e37713c 100644 --- a/R-Interface/jasprcpp_interface.h +++ b/R-Interface/jasprcpp_interface.h @@ -124,6 +124,7 @@ typedef size_t (*logWriteDef) (const void * buf, size_t len); // Calls from rbridge to jaspRCPP RBRIDGE_TO_JASP_INTERFACE void STDCALL jaspRCPP_init(const char* buildYear, const char* version, RBridgeCallBacks *calbacks, sendFuncDef sendToDesktopFunction, pollMessagesFuncDef pollMessagesFunction, logFlushDef logFlushFunction, logWriteDef logWriteFunction, systemDef systemFunc, libraryFixerDef libraryFixerFunc, const char* resultFont, const char * tempDir); +RBRIDGE_TO_JASP_INTERFACE void STDCALL jaspRCPP_init_jaspBase(); RBRIDGE_TO_JASP_INTERFACE void STDCALL jaspRCPP_setDecimalSettings(int numDecimals, bool fixedDecimals, bool normalizedNotation, bool exactPValues); RBRIDGE_TO_JASP_INTERFACE void STDCALL jaspRCPP_setFontAndPlotSettings(const char * resultFont, const int ppi, const char* imageBackground); RBRIDGE_TO_JASP_INTERFACE const char* STDCALL jaspRCPP_runModuleCall(const char* name, const char* title, const char* moduleCall, const char* dataKey, const char* options, const char* stateKey, int analysisID, int analysisRevision, bool developerMode); diff --git a/Resources/Data Sets/Data Library/13. Reliability/ADD symptoms.csv b/Resources/Data Sets/Data Library/13. Reliability/ADD symptoms.csv new file mode 100644 index 0000000000..67a9cf64d3 --- /dev/null +++ b/Resources/Data Sets/Data Library/13. Reliability/ADD symptoms.csv @@ -0,0 +1,1163 @@ +ASSK_1,ASSK_2,ASSK_3,ASSK_4,ASSK_5,ASSK_6,ASSK_7,ASSK_8,ASSK_9 +2,2,1,2,3,2,2,3,4 +0,0,0,0,2,4,1,3,2 +1,0,1,1,1,0,2,0,0 +0,2,0,0,2,0,0,3,0 +1,1,1,0,1,0,1,2,0 +2,3,1,2,2,1,1,3,3 +1,1,1,1,1,1,1,2,1 +1,1,2,2,2,3,1,2,2 +1,1,2,0,0,1,0,1,0 +2,1,3,2,2,2,0,3,1 +1,1,0,0,2,0,0,2,0 +3,3,4,4,4,4,1,4,1 +1,2,2,0,2,2,1,3,0 +1,1,0,1,3,2,2,3,1 +1,1,0,0,1,1,0,1,0 +3,3,0,2,3,3,1,3,2 +1,0,0,0,0,0,0,1,0 +3,2,2,1,2,2,3,3,2 +2,1,2,1,2,3,1,2,1 +0,0,0,0,0,0,0,1,0 +3,3,2,3,2,3,4,3,3 +2,2,2,1,1,2,1,2,1 +3,3,2,3,3,2,2,4,2 +2,1,0,2,1,1,3,3,2 +1,1,3,0,2,2,2,2,2 +2,1,2,1,0,1,0,0,0 +0,1,2,1,1,1,2,2,0 +0,1,2,0,1,1,1,1,1 +2,0,2,0,3,0,3,2,2 +2,1,1,1,0,1,2,1,2 +0,0,0,0,0,0,0,0,0 +2,2,2,2,3,3,3,3,2 +1,1,1,1,1,1,1,1,0 +2,2,0,0,1,2,0,2,1 +2,2,2,2,2,0,1,2,1 +1,0,3,0,0,1,1,1,0 +1,2,0,0,0,0,0,2,0 +2,2,0,0,1,0,0,1,1 +1,1,3,1,1,1,1,2,1 +3,2,2,0,0,2,0,1,0 +1,0,1,0,1,0,1,1,0 +1,2,2,1,1,1,1,2,2 +1,1,2,0,1,1,1,2,1 +2,1,0,1,1,1,2,1,1 +2,1,0,0,1,0,0,1,0 +2,1,2,1,1,0,2,1,0 +1,1,2,1,2,0,0,2,1 +1,2,2,2,0,1,4,4,0 +1,1,1,1,1,1,3,3,2 +1,1,1,1,1,2,2,2,2 +0,1,0,0,2,0,0,2,0 +2,2,2,0,2,1,0,2,0 +3,2,3,2,3,2,2,4,2 +2,2,3,2,2,0,1,3,0 +2,1,2,2,2,4,1,2,1 +0,1,1,0,0,0,0,1,0 +1,1,3,0,1,2,1,2,1 +0,1,0,0,0,0,0,0,0 +0,1,0,0,1,0,1,1,0 +1,1,1,1,2,1,0,2,0 +1,2,1,0,1,1,2,1,0 +2,3,2,1,1,2,1,3,1 +0,0,0,0,0,0,0,0,0 +3,4,2,2,4,3,4,4,2 +0,0,0,0,0,0,0,1,0 +1,1,0,1,1,0,1,2,1 +3,1,2,1,2,2,1,0,1 +1,3,2,1,3,2,2,3,1 +1,3,3,3,2,2,1,4,0 +0,1,0,0,0,0,0,2,0 +3,3,1,3,3,3,3,3,1 +1,1,0,0,1,0,0,2,1 +1,0,1,0,1,0,0,1,1 +1,1,0,1,0,0,0,3,0 +0,0,0,0,0,0,0,1,0 +2,2,2,2,2,2,1,2,2 +2,1,1,0,3,1,4,3,1 +1,1,0,0,1,0,1,1,0 +2,1,2,1,1,1,0,1,0 +1,1,0,1,1,0,1,2,1 +2,1,1,2,2,2,1,1,2 +1,1,1,0,1,1,2,1,1 +2,2,2,1,4,3,0,4,2 +1,1,1,2,0,0,2,0,0 +1,0,0,0,2,2,0,2,0 +2,2,1,2,1,2,2,2,1 +0,2,0,1,2,3,0,1,0 +1,1,2,0,2,0,0,2,0 +0,0,0,0,0,0,0,0,0 +2,2,3,2,2,0,2,3,2 +1,2,0,0,1,1,1,2,2 +1,1,1,1,0,1,0,2,0 +0,0,0,0,0,0,0,0,0 +3,3,2,1,1,3,1,4,3 +2,3,1,1,1,2,1,3,2 +3,1,0,1,1,2,0,2,1 +2,3,1,1,4,4,4,4,4 +2,2,2,1,2,2,1,2,2 +2,2,0,0,1,3,1,2,0 +2,3,3,3,3,3,2,4,4 +4,4,3,4,4,4,4,4,4 +3,2,2,1,1,2,2,2,2 +3,0,3,2,0,2,2,2,3 +2,4,2,1,2,3,0,4,3 +3,2,2,0,0,0,0,1,2 +1,2,2,1,2,1,2,2,1 +3,3,2,2,3,4,2,3,2 +2,1,1,0,2,1,3,1,2 +1,1,0,0,0,0,2,0,0 +3,1,2,2,1,0,1,2,0 +2,0,0,1,2,1,1,2,0 +2,3,2,2,4,3,2,3,2 +1,2,2,1,2,2,2,2,1 +2,2,2,2,2,3,2,3,2 +0,0,0,0,0,0,0,0,0 +2,3,3,1,2,1,2,3,1 +3,2,0,3,4,4,3,1,4 +1,1,2,1,2,2,1,2,2 +3,3,2,3,3,3,3,3,3 +3,3,3,3,2,2,4,4,3 +1,2,0,1,2,1,0,2,0 +1,1,1,1,1,1,1,1,0 +1,1,2,0,2,2,2,3,0 +0,1,1,0,2,0,2,1,0 +2,2,2,2,3,3,1,2,2 +1,1,1,0,0,1,2,1,0 +3,3,1,2,2,3,0,3,0 +2,2,0,1,3,2,0,2,0 +2,0,0,0,0,2,0,0,0 +1,0,0,0,1,1,1,1,0 +0,1,2,2,1,1,1,1,1 +2,1,1,1,0,2,1,2,0 +1,1,1,1,1,1,1,1,1 +1,1,2,1,2,0,2,2,2 +0,2,1,0,0,0,0,2,0 +1,2,2,1,2,2,0,2,0 +2,2,1,1,1,3,0,4,1 +1,1,0,1,1,1,2,1,1 +1,1,2,2,2,0,3,2,0 +2,2,1,2,2,2,1,2,1 +1,2,1,1,1,0,0,1,0 +1,2,2,0,1,1,1,1,1 +2,1,2,1,1,0,1,2,1 +3,2,3,1,2,2,3,4,1 +0,2,3,1,3,1,3,3,2 +1,1,1,1,2,2,2,1,0 +2,2,0,2,2,3,1,2,0 +1,1,2,1,2,1,2,1,2 +1,1,0,1,1,1,0,3,0 +0,0,0,0,0,0,0,0,1 +2,1,0,1,0,0,2,2,0 +2,3,2,1,0,0,3,4,2 +2,2,1,0,1,1,1,2,1 +0,0,1,1,0,0,1,0,0 +2,2,2,1,2,1,2,3,1 +1,1,2,1,1,0,2,2,0 +1,1,1,0,1,1,1,1,1 +1,2,1,1,1,1,1,2,1 +3,4,1,3,4,2,4,4,2 +2,2,2,2,2,2,1,2,0 +1,2,2,1,1,1,1,3,1 +2,1,2,1,1,1,0,2,0 +2,1,2,2,1,1,1,2,0 +1,0,1,1,0,2,2,1,0 +0,0,0,0,0,0,0,0,0 +1,1,1,1,1,1,1,1,1 +1,1,1,0,1,0,1,1,0 +0,2,2,2,1,1,2,2,1 +1,1,0,0,0,1,1,1,1 +0,0,1,0,1,0,0,2,0 +0,0,0,0,2,0,0,2,0 +2,3,2,3,2,2,3,4,2 +2,2,2,3,3,3,2,2,2 +1,0,2,1,0,1,0,1,0 +2,1,2,1,1,1,2,2,1 +2,0,0,0,1,0,0,0,0 +0,0,0,0,0,0,0,1,0 +0,1,0,2,0,0,1,3,1 +0,0,0,0,0,0,0,0,0 +2,1,1,1,1,1,1,2,1 +1,2,0,1,0,2,1,0,2 +2,1,0,0,1,2,0,2,1 +0,1,1,1,0,0,1,1,1 +2,1,2,2,0,0,0,2,2 +0,0,0,0,0,0,0,0,0 +1,1,2,1,2,1,1,2,2 +3,3,3,3,3,2,2,3,3 +2,2,2,1,2,3,1,2,2 +3,2,2,1,3,0,2,1,0 +2,2,3,2,2,2,2,2,1 +1,2,2,1,1,0,1,1,1 +2,1,1,1,2,3,0,3,1 +1,0,0,0,0,0,0,1,0 +1,0,0,0,0,1,2,1,0 +1,1,0,1,2,0,1,2,1 +2,1,2,1,2,0,2,2,2 +2,4,1,2,3,3,1,4,0 +3,2,2,3,3,4,2,3,3 +0,0,1,0,0,0,0,0,0 +1,1,0,0,0,1,2,1,1 +3,3,3,3,2,3,3,3,3 +2,2,0,2,2,2,3,2,2 +0,0,0,1,0,0,0,1,0 +0,1,1,0,0,1,0,0,1 +2,3,0,1,2,1,0,3,0 +1,1,0,1,0,0,0,1,0 +1,0,0,1,2,0,2,2,2 +1,1,1,1,1,1,1,0,0 +2,0,0,1,0,0,0,2,0 +2,2,2,1,1,2,1,1,0 +1,1,2,2,1,0,2,2,1 +2,1,2,1,1,0,1,1,1 +0,0,0,0,0,0,2,2,0 +2,0,0,0,2,1,0,1,2 +3,3,1,3,2,2,2,2,2 +3,3,3,1,1,3,1,4,2 +2,3,1,2,3,2,2,2,2 +2,2,2,2,2,1,3,2,3 +1,0,2,0,0,0,2,2,0 +1,1,2,2,0,1,1,2,1 +1,0,2,1,2,0,1,1,1 +1,1,1,0,0,0,1,1,0 +1,2,1,1,2,1,0,2,1 +0,1,2,0,0,0,1,0,0 +1,0,0,0,1,1,0,1,1 +0,1,1,0,1,1,0,2,0 +2,3,2,2,3,1,2,3,2 +0,0,0,1,0,0,0,0,1 +1,2,2,0,1,1,1,3,0 +4,3,3,2,1,4,1,3,1 +3,3,2,2,3,4,0,4,4 +1,2,0,1,0,2,0,3,0 +1,0,2,0,1,1,1,2,0 +2,2,1,2,2,2,0,3,0 +3,2,2,1,1,2,2,3,2 +2,2,1,1,2,2,1,2,0 +0,0,4,1,2,4,0,0,0 +2,1,3,2,3,2,1,2,2 +1,1,0,0,1,0,1,1,0 +2,3,0,3,3,2,4,3,2 +2,3,1,1,2,3,2,4,1 +3,3,1,3,3,4,3,3,3 +1,0,0,0,1,0,1,1,1 +1,1,0,1,0,1,0,1,0 +2,1,0,1,2,2,2,2,0 +2,1,1,1,1,1,1,1,0 +2,0,0,0,1,1,0,3,1 +1,1,2,1,1,0,0,1,1 +2,1,1,0,1,1,1,1,1 +2,0,0,0,0,0,0,0,0 +2,1,1,1,1,2,2,1,1 +2,1,2,0,0,0,2,2,1 +1,1,0,0,1,1,1,2,1 +1,2,2,3,3,2,3,4,3 +2,2,1,1,2,2,1,2,1 +1,1,0,0,1,0,0,0,0 +2,2,1,1,1,1,1,1,1 +1,1,1,1,1,1,2,2,2 +1,1,2,0,0,0,0,2,1 +4,4,2,3,4,3,3,4,3 +0,2,1,0,0,0,1,0,0 +2,1,1,1,1,2,2,2,1 +1,1,1,1,1,2,2,1,1 +2,1,2,0,0,0,0,2,2 +2,2,0,0,2,2,2,3,2 +1,0,1,1,0,1,1,1,0 +1,0,1,0,1,0,1,0,1 +0,2,2,2,4,2,1,4,0 +1,1,0,0,1,1,1,0,1 +2,2,2,1,3,1,3,3,3 +2,1,2,1,2,3,1,3,1 +1,0,2,0,0,0,0,2,0 +1,2,2,0,2,1,3,2,1 +1,1,0,0,1,1,2,0,0 +3,2,2,1,2,1,2,2,2 +2,2,2,1,2,1,2,2,2 +1,1,0,1,2,2,1,2,2 +0,0,1,0,0,1,1,1,1 +2,1,1,1,1,2,2,1,0 +2,2,1,1,3,1,0,3,1 +2,1,3,1,1,2,3,3,1 +2,2,3,1,2,1,0,3,1 +1,1,0,1,2,2,1,3,0 +2,2,0,2,1,2,2,1,0 +2,1,2,0,2,1,2,2,1 +3,3,2,1,3,3,3,3,2 +1,1,0,0,2,0,0,1,1 +2,2,0,0,1,2,2,3,2 +1,1,1,1,1,1,2,1,1 +2,1,0,1,0,2,1,1,1 +0,2,3,2,2,2,2,2,1 +1,1,2,1,1,2,0,0,0 +0,0,0,0,0,0,0,0,0 +0,0,1,0,1,0,1,1,0 +1,1,1,1,0,1,0,1,0 +1,2,2,1,3,1,0,3,2 +1,1,0,3,0,0,0,3,0 +0,1,1,0,0,0,0,1,0 +2,1,1,1,1,2,1,2,1 +1,0,0,0,0,0,0,2,0 +2,1,2,2,1,2,1,1,0 +1,1,0,1,2,0,2,2,0 +2,3,1,2,2,2,0,3,0 +0,0,0,1,0,1,0,0,0 +0,0,0,0,0,0,0,0,0 +1,1,1,1,1,1,0,1,0 +3,2,1,2,1,2,2,3,0 +2,1,2,1,3,3,2,3,2 +0,0,0,0,0,0,0,0,0 +2,1,0,1,1,0,3,1,2 +3,3,1,3,3,3,1,3,3 +0,1,0,0,2,0,1,1,0 +2,1,0,0,0,1,0,0,0 +1,1,1,1,1,1,2,1,0 +2,2,3,1,1,2,1,2,1 +1,0,2,0,1,0,1,0,0 +1,0,2,0,2,0,4,0,1 +0,0,0,0,0,0,0,0,0 +2,1,0,1,0,1,2,2,1 +3,3,2,2,2,3,2,3,1 +1,1,1,0,1,0,0,2,1 +1,0,0,1,0,0,1,0,0 +1,1,3,2,0,0,2,1,1 +2,2,2,1,3,3,2,3,1 +1,1,0,0,1,0,2,0,1 +0,2,2,1,0,2,0,2,0 +1,0,0,0,0,0,0,2,0 +2,2,0,0,2,2,3,2,3 +0,0,2,1,0,0,0,0,0 +1,1,1,1,0,1,0,2,1 +3,3,3,3,2,4,3,3,3 +3,4,4,4,4,2,4,2,4 +0,1,2,0,0,0,0,0,0 +1,0,2,0,2,0,0,0,0 +2,1,2,2,1,3,0,2,3 +2,2,0,1,4,2,0,4,1 +1,2,3,1,1,1,1,3,1 +2,3,3,1,3,3,4,4,4 +4,4,3,4,4,4,2,3,3 +1,2,2,0,1,0,2,3,2 +0,0,0,1,1,1,1,2,1 +3,2,1,1,3,3,0,4,0 +2,2,2,2,2,2,2,3,2 +0,2,1,1,2,1,2,1,1 +1,1,2,1,0,0,0,2,0 +2,1,0,0,1,1,0,1,0 +1,0,1,0,0,1,1,0,0 +1,2,0,0,2,1,2,2,1 +0,0,0,0,2,0,0,1,0 +2,2,2,1,1,1,0,2,0 +1,1,2,1,1,1,1,1,1 +1,3,2,2,1,2,1,3,1 +2,1,0,1,2,0,2,3,1 +1,1,1,1,0,0,1,0,0 +0,1,0,0,1,0,0,2,0 +2,3,3,3,3,2,3,4,3 +1,0,1,1,1,1,1,1,0 +1,1,1,0,0,1,1,1,0 +2,1,2,2,0,0,2,2,2 +0,0,1,0,0,0,0,1,0 +1,1,2,1,1,1,1,2,1 +1,0,1,1,1,2,1,2,1 +1,1,2,1,2,3,2,2,2 +0,0,0,0,0,0,0,0,0 +0,0,0,0,2,0,0,0,0 +0,0,0,0,2,0,0,0,0 +0,0,0,0,0,0,0,0,0 +2,2,0,0,0,2,0,3,0 +2,2,1,1,1,1,2,2,1 +2,3,2,2,1,3,2,3,2 +2,3,1,2,2,1,2,3,2 +1,0,1,1,1,0,1,0,1 +1,0,0,2,0,0,0,2,3 +1,0,2,0,1,1,0,0,0 +2,2,2,2,2,2,1,2,3 +1,0,0,0,0,0,0,2,0 +0,0,0,0,0,0,0,1,0 +2,2,1,0,0,0,2,4,0 +1,0,1,1,1,0,2,2,2 +1,1,1,0,2,2,3,2,0 +0,1,0,0,1,0,0,1,1 +2,2,2,2,3,3,2,3,1 +1,0,0,1,0,0,1,1,0 +0,3,0,2,1,2,0,2,0 +3,3,3,2,3,3,3,3,3 +2,2,1,0,0,1,0,1,0 +1,3,1,1,4,3,4,4,1 +1,3,0,4,4,3,1,3,2 +4,4,2,0,3,2,1,4,4 +2,2,3,2,2,3,4,4,2 +1,1,1,0,1,1,1,1,1 +1,3,0,1,3,2,0,3,0 +2,0,1,1,0,2,1,3,0 +0,0,0,0,0,1,1,1,0 +0,1,2,1,0,0,2,2,2 +1,1,1,1,2,2,1,3,1 +1,1,1,1,1,1,1,1,1 +0,0,1,0,0,0,2,1,1 +3,3,2,3,2,4,4,4,2 +2,3,2,1,2,2,0,3,0 +0,0,1,0,0,0,0,0,0 +1,1,2,0,0,0,1,2,0 +1,1,0,1,1,1,1,1,1 +0,0,1,0,0,0,0,0,0 +1,1,0,1,1,0,0,1,0 +1,0,0,0,0,1,1,1,0 +1,2,2,1,0,0,3,3,2 +3,2,2,2,2,3,2,3,1 +1,2,3,2,3,1,2,4,2 +2,2,1,1,1,3,1,2,0 +1,1,0,0,1,2,1,1,1 +3,4,2,3,3,2,2,4,2 +1,0,3,0,1,2,1,1,2 +1,2,1,1,1,2,2,3,0 +3,3,0,2,2,3,2,3,1 +1,1,2,1,1,0,1,1,0 +2,2,2,3,2,1,2,3,1 +2,2,2,1,2,1,2,1,1 +1,1,2,1,2,1,1,2,0 +2,2,3,2,1,4,1,2,2 +0,0,0,0,0,0,0,0,0 +1,1,2,1,2,1,1,2,3 +2,2,2,1,0,0,1,2,1 +2,2,1,2,1,0,2,2,2 +1,1,1,1,1,1,1,1,1 +2,2,1,1,1,2,1,3,2 +1,2,2,0,0,1,2,2,0 +2,2,2,2,2,1,1,2,3 +1,1,2,0,1,0,2,2,0 +1,1,0,0,1,0,2,1,0 +1,1,1,1,1,1,2,1,2 +2,1,0,1,2,2,1,1,1 +2,1,2,2,0,1,2,3,0 +3,2,2,0,1,1,0,2,2 +2,2,0,2,0,2,0,2,2 +2,2,2,1,1,0,1,3,1 +0,1,1,0,1,0,1,1,0 +1,0,1,2,1,1,1,1,0 +2,2,2,1,1,1,4,2,2 +2,2,2,2,2,3,2,4,2 +2,2,3,1,1,1,1,3,1 +2,1,0,0,1,2,0,1,0 +2,2,2,2,2,2,2,2,2 +3,3,2,3,2,3,2,3,1 +3,2,1,1,2,2,1,2,1 +2,2,2,1,1,1,0,2,2 +2,1,3,2,0,2,1,1,0 +2,2,2,0,2,2,1,1,0 +1,3,2,2,2,2,2,3,3 +3,2,2,2,3,3,3,4,3 +2,2,1,2,2,2,2,2,1 +1,2,2,0,2,3,0,4,0 +1,0,1,0,1,0,1,2,0 +2,3,3,3,3,2,3,3,3 +1,1,2,1,0,1,1,1,1 +2,2,2,2,3,1,3,2,2 +0,0,2,0,0,0,2,2,0 +2,3,2,2,3,3,3,4,2 +2,0,1,2,2,2,0,2,0 +1,0,0,0,1,1,1,1,1 +2,1,0,0,2,0,3,2,0 +1,1,1,1,1,0,2,1,1 +1,1,0,1,1,1,1,1,0 +2,1,2,0,1,2,1,2,0 +2,2,1,0,2,3,3,3,0 +1,2,1,1,0,1,0,2,0 +1,1,2,1,0,0,1,0,0 +1,2,1,2,3,3,1,3,3 +2,3,2,2,3,2,2,3,2 +1,2,3,1,1,1,1,2,1 +1,0,0,0,0,0,0,0,0 +2,2,1,1,2,1,2,3,2 +3,4,2,2,4,4,0,4,2 +0,0,2,0,1,0,2,2,0 +2,2,1,1,1,1,1,1,1 +1,1,1,0,1,0,1,0,0 +1,0,1,1,2,0,0,0,0 +2,1,1,2,1,1,1,1,1 +1,1,1,1,1,1,2,1,1 +4,4,3,3,4,3,4,4,4 +1,2,2,0,1,0,0,2,0 +2,2,2,1,1,0,3,2,0 +2,3,2,0,2,2,3,4,2 +1,2,2,2,2,1,1,2,1 +2,2,2,1,2,2,2,2,2 +2,2,0,2,0,0,3,3,0 +0,0,1,1,2,1,0,2,0 +2,1,1,1,1,1,2,2,1 +1,1,2,0,1,1,1,1,2 +2,1,2,1,0,2,0,2,0 +1,2,1,1,2,2,2,2,1 +1,1,1,2,1,1,3,2,2 +2,2,2,1,3,0,3,3,2 +2,1,0,0,1,0,1,1,0 +2,2,1,1,3,2,3,2,2 +2,1,2,0,1,0,0,2,0 +2,3,1,2,2,3,1,3,2 +1,2,0,2,0,0,0,0,0 +0,0,0,0,2,1,0,1,0 +3,1,2,2,1,4,0,2,0 +1,0,1,0,1,0,2,0,0 +1,1,1,1,1,1,2,2,2 +1,1,2,0,2,0,0,2,0 +1,1,1,2,1,0,1,1,0 +2,3,2,2,2,3,1,4,2 +2,2,2,2,2,2,2,2,2 +2,2,3,2,2,1,1,3,0 +1,2,2,0,3,0,2,2,1 +0,2,0,1,2,0,1,2,1 +2,1,1,0,1,1,0,2,1 +2,3,2,3,2,3,2,4,2 +1,1,1,0,1,1,1,1,0 +1,1,2,1,1,1,2,2,2 +2,2,0,0,1,1,1,2,1 +1,2,2,2,1,2,0,3,0 +0,0,0,0,0,0,0,0,0 +1,2,2,0,1,1,2,2,0 +0,1,1,0,1,0,1,1,1 +2,2,2,2,1,1,1,1,1 +2,2,2,1,2,2,1,2,0 +1,1,1,1,1,1,2,0,2 +2,2,1,2,2,2,0,2,0 +2,3,3,3,3,3,3,3,3 +2,2,2,2,2,2,2,2,2 +3,2,3,3,3,3,3,4,3 +1,1,0,0,0,1,0,2,2 +2,2,0,0,2,2,1,3,0 +0,2,1,0,0,1,0,2,0 +1,2,2,1,2,1,2,2,1 +1,2,1,1,3,2,2,3,1 +1,1,2,1,1,0,1,2,0 +2,3,2,1,1,1,0,2,2 +1,0,0,0,0,0,0,0,0 +2,0,1,0,1,1,2,2,0 +2,2,2,0,4,3,3,4,1 +2,1,0,0,0,3,0,2,1 +2,2,0,2,0,0,2,2,0 +2,2,4,1,2,3,1,2,3 +1,1,1,0,2,1,2,2,0 +2,2,1,1,0,2,1,2,1 +2,3,1,2,3,2,1,3,1 +2,2,2,2,3,2,1,3,2 +2,2,3,1,1,1,1,2,2 +2,2,1,2,2,1,1,1,0 +1,0,2,0,1,1,1,0,1 +0,1,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0 +3,2,1,2,3,1,0,2,1 +1,0,0,0,1,0,1,0,0 +1,1,1,0,0,0,1,2,1 +2,2,2,2,2,2,2,2,2 +1,2,1,1,2,1,1,3,0 +2,2,2,1,2,1,1,1,0 +0,1,0,0,1,1,1,2,0 +1,0,0,1,0,1,0,0,0 +1,1,3,1,1,2,4,1,0 +1,1,1,0,1,0,0,1,1 +1,1,1,0,0,0,1,2,1 +3,2,2,2,2,1,1,1,2 +1,1,3,1,1,2,1,3,1 +1,1,0,1,0,0,0,2,0 +2,2,0,2,2,2,2,2,0 +2,1,2,1,2,1,0,2,1 +2,3,1,3,3,2,3,3,2 +2,2,0,0,0,2,1,3,1 +2,2,2,2,2,2,2,2,2 +2,2,2,0,1,0,1,1,0 +1,0,3,1,1,2,0,1,0 +1,2,3,1,0,0,2,3,0 +2,0,2,0,0,2,0,1,0 +3,3,0,1,2,2,2,3,0 +2,2,1,2,2,2,1,3,0 +1,2,2,1,2,1,3,3,1 +1,2,1,1,1,1,3,2,2 +2,2,2,2,2,3,1,2,1 +1,2,3,0,1,1,1,3,0 +3,2,3,2,2,3,0,4,2 +1,1,2,2,0,2,0,3,1 +1,1,1,0,0,1,1,0,0 +1,2,2,2,2,0,1,2,2 +0,2,1,0,0,0,1,1,0 +1,1,1,0,0,0,0,1,0 +1,0,2,2,2,0,1,1,1 +2,0,0,1,1,2,1,1,0 +1,2,1,1,2,1,0,3,1 +2,2,2,3,2,2,1,2,1 +2,2,2,1,3,3,2,4,3 +2,2,0,0,1,0,0,2,0 +1,1,0,1,1,1,1,1,2 +1,0,0,0,0,0,0,0,0 +2,2,2,2,2,2,1,2,1 +2,2,2,1,2,2,2,2,1 +2,2,2,2,2,2,2,3,2 +0,0,0,0,0,1,0,0,0 +0,1,1,0,0,0,0,0,0 +0,1,0,0,0,0,0,0,0 +1,3,2,2,1,3,2,3,1 +1,2,2,1,1,0,0,2,0 +1,1,1,0,1,0,1,1,0 +1,1,0,0,1,0,0,1,1 +1,0,2,1,2,0,0,1,0 +2,2,1,1,2,1,2,2,2 +1,2,1,1,2,1,1,2,1 +2,2,2,2,2,2,2,2,2 +2,2,3,1,3,2,2,4,2 +1,2,2,1,0,0,0,0,0 +1,1,2,1,1,2,2,2,1 +2,2,2,1,2,2,2,2,0 +2,2,2,2,2,2,2,2,1 +3,0,3,0,0,0,1,0,0 +1,1,1,1,1,1,1,1,1 +2,3,3,2,3,2,2,2,1 +1,2,1,1,1,2,2,2,0 +1,3,1,0,1,0,3,4,0 +3,3,2,2,3,3,2,3,1 +1,1,0,1,1,2,0,3,0 +2,1,0,1,0,1,1,1,0 +2,2,2,2,2,2,2,2,2 +2,1,0,0,0,2,0,2,0 +1,1,1,0,1,1,0,1,0 +0,0,0,0,0,0,0,0,0 +1,2,0,1,1,1,2,2,1 +0,0,0,0,0,0,0,1,0 +2,2,2,1,1,2,1,2,0 +1,0,1,0,1,0,1,0,0 +2,1,1,1,1,1,1,1,2 +1,1,2,1,2,1,2,2,1 +1,1,2,1,1,1,1,2,1 +2,0,2,0,0,0,0,2,0 +1,1,1,0,0,1,1,2,0 +2,3,3,2,2,2,1,3,1 +2,2,2,2,1,2,2,2,2 +2,2,2,1,2,1,2,2,1 +1,2,2,0,3,2,2,3,2 +1,3,4,3,3,4,3,4,1 +2,1,2,1,2,2,2,2,2 +0,0,0,0,0,0,1,0,0 +2,2,1,1,2,1,1,2,1 +0,0,2,0,0,0,0,1,0 +1,2,0,0,1,1,1,2,0 +1,2,3,0,1,1,0,1,1 +1,3,2,2,2,0,1,3,0 +2,2,1,1,2,1,2,3,2 +2,1,1,2,2,2,2,3,2 +2,0,2,1,1,2,2,1,1 +2,2,2,2,2,3,3,2,2 +2,3,1,2,1,0,2,3,0 +2,4,2,3,2,2,2,4,2 +1,1,1,1,2,1,1,1,0 +2,1,1,0,0,0,2,0,2 +0,2,2,0,0,0,0,2,0 +1,2,1,1,1,1,1,3,1 +1,1,2,1,2,2,3,2,2 +2,2,2,1,2,2,2,2,2 +1,1,1,1,0,1,1,2,2 +1,1,0,0,0,1,0,1,0 +1,2,2,1,2,0,2,2,2 +1,2,1,1,0,0,2,0,1 +1,2,2,2,1,0,0,2,0 +3,2,1,1,1,1,2,3,0 +0,0,0,0,0,0,0,0,0 +2,1,2,1,1,2,1,2,2 +1,2,1,0,0,0,1,2,0 +2,2,4,2,2,2,3,4,0 +2,2,2,2,2,0,1,2,2 +0,4,4,0,4,4,0,4,4 +0,0,0,0,0,0,0,0,0 +2,2,2,2,2,2,2,2,2 +0,1,0,0,0,0,1,0,0 +3,3,1,1,2,2,3,3,2 +4,2,3,2,4,2,4,2,4 +2,3,1,2,2,3,2,4,2 +2,1,1,1,2,0,0,2,0 +1,2,2,1,2,1,2,2,2 +2,2,2,2,2,2,2,2,2 +2,2,0,0,2,2,2,2,0 +2,1,0,0,1,2,0,2,2 +2,2,1,1,1,2,1,2,2 +2,1,1,0,2,0,1,2,0 +1,1,2,2,2,2,1,2,2 +0,1,0,0,0,0,0,0,0 +2,2,0,0,0,1,1,3,2 +2,1,2,1,2,0,1,2,0 +1,2,1,2,2,2,2,3,1 +1,0,2,0,1,0,1,2,1 +2,3,2,1,1,0,2,4,0 +0,0,0,0,0,0,0,0,0 +1,1,2,0,1,2,1,3,0 +1,2,1,1,2,1,2,2,1 +2,1,2,1,1,3,1,2,2 +2,2,2,2,2,2,2,2,2 +2,2,3,2,3,0,2,4,3 +2,2,2,1,2,2,1,2,2 +2,2,3,2,1,1,3,3,2 +1,2,0,0,3,2,3,3,2 +2,2,2,3,2,3,2,2,2 +1,0,0,0,0,0,0,0,0 +3,1,0,2,1,3,0,1,1 +1,1,0,1,0,0,0,1,1 +1,2,1,1,1,1,1,2,1 +1,1,2,0,1,1,0,1,0 +2,2,1,1,1,2,1,3,1 +0,0,2,1,2,1,0,2,1 +1,3,2,0,1,0,0,1,0 +2,2,2,2,3,0,0,3,1 +2,1,3,2,2,3,1,1,4 +1,2,2,2,2,1,2,1,0 +0,1,1,2,1,1,1,1,0 +1,2,1,3,3,2,2,3,2 +3,2,2,3,3,2,3,2,1 +3,1,3,2,3,3,2,2,1 +1,2,0,1,2,0,0,3,0 +1,1,0,0,0,0,1,1,0 +1,2,2,1,1,1,1,2,1 +1,1,0,1,1,1,0,2,1 +0,1,1,1,1,0,1,2,1 +1,1,0,0,2,0,0,2,0 +1,0,2,1,1,1,1,2,1 +1,1,0,1,1,1,0,0,0 +0,0,0,0,1,0,0,0,0 +0,0,0,0,1,0,0,1,0 +2,2,2,0,3,2,4,2,0 +2,3,3,3,3,2,1,4,1 +1,2,2,2,2,1,1,2,2 +1,0,1,0,1,1,0,1,1 +0,1,1,0,1,1,0,1,1 +1,2,2,2,2,2,3,2,1 +1,2,2,0,0,1,2,2,1 +1,0,0,0,0,0,2,0,0 +2,2,1,1,1,0,0,2,0 +3,2,2,2,2,2,2,2,2 +2,1,3,1,1,2,2,4,1 +1,1,1,1,2,2,2,2,2 +1,2,2,1,2,2,1,3,2 +2,2,0,1,2,1,1,4,0 +1,1,0,1,1,2,1,2,0 +1,2,1,1,1,2,1,2,1 +2,2,3,1,2,3,0,3,2 +1,1,2,0,0,0,2,1,2 +0,0,0,0,1,0,0,2,0 +3,3,2,3,4,3,2,4,3 +1,1,1,1,1,1,1,2,0 +1,2,1,1,2,2,2,2,2 +0,1,0,1,1,2,1,2,1 +1,2,2,1,1,1,2,2,2 +1,1,2,1,1,1,0,1,0 +2,2,3,3,2,2,1,2,0 +0,2,3,2,1,0,1,3,0 +1,1,1,1,1,1,1,2,1 +1,2,0,1,2,2,1,2,1 +2,2,2,1,1,2,0,2,2 +1,1,2,2,1,2,0,2,0 +1,1,4,2,0,0,2,2,1 +2,3,0,2,0,1,0,3,0 +3,1,2,2,1,1,1,3,2 +1,1,1,2,2,2,1,1,1 +1,2,0,2,2,0,0,3,0 +0,0,0,0,0,0,0,0,0 +2,3,0,0,2,2,0,4,0 +2,2,1,1,2,1,1,2,1 +2,2,2,2,2,2,2,2,2 +0,0,0,0,0,0,0,0,0 +1,2,0,0,0,1,2,2,2 +0,2,2,0,0,0,2,2,2 +2,2,1,1,2,2,1,1,1 +1,1,2,1,1,1,1,1,1 +1,2,2,1,2,2,2,2,0 +2,1,0,1,1,1,1,2,1 +0,1,2,0,1,1,2,3,1 +0,2,2,0,0,0,0,3,1 +2,2,2,2,2,3,2,3,1 +1,1,0,1,1,1,2,0,0 +1,0,0,0,0,0,0,0,1 +0,2,1,1,1,2,0,3,0 +0,1,1,0,0,1,0,1,0 +1,1,1,1,0,0,0,1,0 +0,0,0,0,0,1,1,2,1 +1,0,2,0,0,0,1,1,0 +2,2,0,0,1,0,2,3,2 +1,1,2,2,1,2,2,2,1 +1,1,1,2,1,1,0,0,1 +1,2,2,2,2,2,0,2,0 +2,1,1,0,1,0,2,1,1 +2,1,0,1,1,2,1,2,1 +2,1,2,2,2,2,2,2,2 +1,0,2,0,0,1,0,2,0 +0,0,0,0,0,0,0,1,0 +1,1,0,1,0,0,1,0,0 +2,2,3,2,1,3,1,3,1 +2,2,1,0,0,0,0,0,0 +2,2,2,0,1,2,2,2,1 +2,0,2,0,2,4,1,3,1 +3,2,2,3,2,3,2,2,2 +0,0,1,0,0,0,0,0,0 +1,0,0,1,0,1,0,1,0 +2,2,3,1,3,2,1,4,2 +1,1,1,1,1,0,1,1,1 +1,2,2,2,2,1,2,2,2 +1,1,2,0,0,2,0,2,2 +2,2,3,2,1,3,3,4,2 +1,2,2,0,1,0,2,3,1 +2,3,2,2,3,1,3,3,2 +0,0,0,0,0,0,0,1,0 +1,1,0,1,1,0,0,0,0 +2,3,0,2,2,1,0,3,0 +1,2,1,1,2,1,0,2,2 +1,1,1,0,1,0,0,2,1 +1,3,2,1,0,1,2,3,0 +1,1,0,0,1,0,0,1,0 +2,3,2,1,3,2,1,3,1 +2,1,1,1,2,2,2,2,1 +2,3,3,0,2,0,2,4,0 +1,0,2,1,0,1,1,0,2 +2,2,1,2,2,1,2,1,0 +1,0,1,0,1,0,1,1,0 +1,1,0,1,0,2,1,1,1 +3,2,1,1,2,2,1,3,1 +0,1,2,0,1,2,0,1,0 +0,1,0,0,1,0,1,1,2 +3,1,1,1,0,1,2,2,0 +3,3,3,3,3,4,2,3,3 +4,3,4,3,4,4,3,4,2 +2,1,1,0,2,0,0,1,0 +1,2,1,1,0,1,1,3,0 +0,0,1,1,1,0,3,0,2 +2,1,1,0,1,0,3,3,2 +0,2,2,0,1,1,2,2,0 +1,1,1,1,1,1,1,2,1 +2,2,2,2,3,3,0,3,2 +3,2,2,2,2,2,2,2,2 +1,1,2,0,1,1,2,2,1 +1,1,2,0,0,2,0,2,1 +2,2,2,3,2,3,2,3,2 +1,0,1,0,0,0,2,0,0 +1,1,1,0,2,0,1,1,0 +0,0,0,0,0,0,0,1,0 +0,1,1,1,1,1,1,1,1 +2,3,1,1,0,2,0,3,2 +2,2,1,2,0,0,1,2,2 +3,3,2,2,2,3,1,3,2 +1,1,2,0,1,0,0,1,0 +2,1,1,2,3,3,2,1,2 +0,0,0,0,0,0,0,0,0 +1,2,1,0,2,1,0,2,1 +2,2,1,0,1,0,2,3,0 +2,2,2,2,0,0,1,2,2 +2,2,2,1,0,0,2,0,0 +1,0,1,0,0,1,0,2,0 +1,1,2,1,2,1,2,2,1 +1,0,1,1,1,1,1,1,1 +2,1,1,1,0,1,2,0,1 +3,2,2,2,2,0,2,0,2 +1,1,1,0,0,1,0,1,0 +2,2,2,2,1,1,3,2,1 +1,1,0,1,1,1,0,1,0 +1,1,2,1,0,0,2,0,0 +3,3,2,2,2,2,1,3,0 +0,0,0,0,0,0,0,2,0 +1,2,1,2,1,1,1,1,1 +1,1,0,1,1,0,0,1,0 +0,0,1,0,0,0,0,1,0 +0,1,0,0,0,0,0,0,0 +2,2,2,0,1,1,2,1,1 +1,2,2,0,2,1,0,3,0 +2,1,2,3,2,2,0,3,0 +2,2,3,2,4,2,2,4,2 +1,2,0,1,1,1,1,2,1 +2,2,1,0,0,0,0,0,0 +1,1,2,1,1,0,2,2,1 +2,2,2,3,2,3,2,4,0 +2,2,2,2,2,0,2,3,1 +1,1,1,1,1,1,0,1,0 +0,2,2,0,2,0,0,2,0 +2,2,1,1,2,2,2,3,1 +1,1,1,1,1,1,1,2,2 +2,2,2,2,1,3,2,1,1 +1,1,1,1,1,1,1,1,1 +1,2,2,1,1,1,1,2,1 +2,2,2,1,2,3,1,3,2 +1,0,0,1,2,0,0,0,1 +1,1,1,3,4,3,4,4,4 +2,2,0,2,0,2,0,3,0 +2,2,2,1,2,1,1,3,1 +2,2,0,1,2,2,2,2,0 +1,3,2,1,2,2,2,3,1 +0,1,0,1,0,0,0,2,0 +2,2,3,2,2,2,2,3,2 +0,0,0,1,0,0,0,0,0 +2,2,3,0,2,0,2,3,3 +2,2,2,2,2,1,0,3,0 +2,2,1,2,2,2,1,2,1 +2,1,2,2,1,2,1,3,1 +1,1,2,1,1,1,1,2,2 +1,1,2,0,0,0,1,2,2 +2,1,1,0,0,0,1,2,1 +1,2,2,0,1,2,1,1,1 +2,3,2,2,2,2,2,3,2 +1,2,2,0,0,1,0,2,0 +1,1,1,2,2,0,1,1,1 +3,1,1,1,1,2,1,3,1 +2,3,2,2,2,2,2,3,2 +2,3,2,2,2,2,2,2,2 +1,0,0,1,0,0,1,0,0 +2,2,0,0,1,2,3,2,2 +1,2,3,0,2,1,2,3,1 +2,2,2,1,1,2,2,2,1 +1,1,2,0,1,2,0,3,2 +0,2,2,0,0,0,0,2,0 +0,0,3,0,0,1,0,0,0 +0,0,0,0,0,0,0,0,0 +2,1,2,1,0,0,1,1,0 +1,0,0,0,0,1,0,1,0 +0,1,0,0,1,0,1,0,1 +1,1,2,1,0,2,0,1,0 +2,2,1,2,2,2,1,3,2 +2,1,2,1,1,1,1,1,1 +0,1,0,0,1,0,0,2,0 +2,2,1,2,2,1,2,2,0 +2,2,1,1,2,2,1,3,1 +3,3,2,1,2,1,1,3,2 +0,1,0,1,0,4,1,2,0 +3,2,3,3,3,4,3,3,3 +1,2,2,1,2,2,0,1,0 +0,0,0,0,1,0,0,1,0 +3,3,1,2,3,3,1,2,0 +0,2,0,0,0,0,0,1,2 +2,0,0,1,1,1,2,3,2 +2,2,1,1,2,2,2,3,3 +2,2,2,1,0,2,2,2,2 +1,1,1,0,1,1,1,1,1 +2,2,2,1,2,1,0,2,2 +2,2,1,1,2,2,1,3,0 +2,2,2,2,1,2,1,3,2 +2,2,1,1,1,1,2,1,1 +1,1,0,0,1,1,1,2,0 +1,0,0,0,0,0,0,0,0 +1,1,0,1,2,0,2,1,2 +1,1,1,2,1,0,2,1,0 +2,2,1,1,1,0,0,1,0 +2,0,2,1,3,4,0,1,0 +2,0,0,0,0,0,0,1,0 +1,2,2,1,2,2,1,2,1 +1,1,0,0,1,1,1,1,0 +3,2,1,1,2,2,1,1,2 +3,2,1,2,3,0,3,4,2 +0,0,0,0,0,0,0,0,0 +2,2,2,1,1,1,1,2,0 +2,2,4,2,0,0,0,4,2 +2,2,0,3,2,3,2,3,2 +2,3,2,3,2,3,2,3,3 +2,2,0,3,2,2,3,2,2 +1,2,2,0,2,2,2,2,1 +2,1,2,0,1,2,2,2,0 +2,2,2,0,0,2,0,3,0 +2,2,1,1,1,0,2,2,0 +0,1,1,1,0,1,1,1,1 +3,3,2,2,1,3,1,3,3 +1,2,3,1,0,0,0,3,2 +2,2,2,2,1,2,0,2,1 +0,1,1,1,1,1,1,1,1 +1,1,0,1,1,1,1,1,1 +2,0,1,0,2,2,1,1,1 +1,1,0,0,0,1,0,1,0 +1,0,2,2,1,1,0,2,1 +1,2,0,0,1,0,1,1,1 +2,2,2,2,0,2,2,2,1 +1,0,0,1,3,0,1,0,0 +2,4,3,3,3,3,4,4,3 +2,2,2,1,1,2,2,2,2 +3,0,3,3,2,3,2,3,3 +1,3,1,2,4,1,2,4,3 +2,1,1,2,2,0,2,2,2 +0,1,0,0,0,0,0,1,0 +1,1,3,1,1,0,1,2,1 +2,2,0,1,1,1,0,2,1 +2,2,2,2,1,1,0,3,0 +2,2,1,1,2,2,2,2,2 +1,1,1,0,1,1,1,1,1 +0,0,1,0,1,1,1,1,1 +0,0,0,0,1,2,3,0,1 +2,3,2,2,2,2,1,3,1 +2,1,2,1,2,1,2,2,1 +0,0,2,0,2,1,1,0,0 +2,2,2,2,2,2,1,2,0 +2,2,1,1,2,2,2,2,2 +0,1,3,1,2,2,1,3,1 +2,2,2,3,2,1,2,3,2 +2,1,2,0,2,2,2,2,1 +1,1,1,1,1,1,0,1,1 +2,2,0,0,0,2,2,2,0 +3,2,2,2,3,3,3,3,2 +2,2,3,2,2,2,1,3,1 +0,2,2,0,1,0,2,3,0 +2,2,0,0,2,0,0,2,0 +2,1,0,0,0,0,0,2,0 +0,2,3,1,0,0,2,2,1 +0,0,2,0,0,1,0,2,1 +2,1,1,1,1,1,1,1,1 +2,2,3,2,3,2,2,2,2 +1,2,1,0,0,1,2,2,3 +1,2,3,0,0,0,0,3,0 +2,1,2,1,2,1,1,3,0 +2,1,1,1,1,2,1,2,0 +1,2,0,0,0,0,0,2,0 +0,0,0,0,0,0,0,0,0 +2,2,2,3,3,2,2,3,2 +1,1,1,0,1,1,0,1,0 +1,1,0,0,0,0,0,0,0 +0,1,2,1,0,2,0,3,2 +1,2,2,2,2,2,2,2,2 +1,0,0,0,0,0,1,1,0 +1,1,0,0,0,0,1,1,1 +2,2,2,1,0,0,0,0,0 +2,2,3,2,2,2,3,3,1 +1,2,0,1,2,3,1,3,1 +1,1,0,0,2,1,0,2,0 +2,2,2,2,2,3,2,4,2 +1,1,2,2,2,2,2,2,1 +3,3,1,2,2,2,2,4,2 +1,2,3,3,3,1,1,3,2 +1,1,0,1,1,1,0,1,0 +1,0,1,0,0,1,1,2,0 +0,1,0,1,0,1,0,1,0 +1,2,0,0,1,2,1,2,0 +1,0,2,2,1,0,0,1,0 +2,2,2,2,3,2,2,3,3 +3,2,2,1,1,0,1,2,2 +2,2,1,2,3,4,4,3,3 +0,0,0,0,0,0,0,0,0 +2,2,2,0,1,0,2,2,1 +2,2,1,1,1,1,1,1,1 +3,3,3,3,2,3,2,3,2 +3,3,2,2,3,2,1,3,1 +0,0,0,0,0,0,0,0,0 +1,1,1,1,1,1,1,2,1 +1,1,1,1,2,1,0,2,0 +0,0,0,0,0,0,0,1,1 +2,2,2,1,2,3,2,2,2 +2,2,1,1,2,1,1,3,1 +1,1,1,1,1,1,1,1,1 +0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0 +1,1,1,0,0,0,0,1,0 +2,2,1,1,1,0,2,2,1 +1,2,0,1,1,1,1,2,1 +1,3,2,2,2,0,0,3,1 +2,1,1,1,2,1,1,1,1 +1,2,2,0,2,1,2,2,1 +2,1,2,2,1,1,1,2,1 +2,1,2,3,2,3,2,3,2 +1,1,1,1,1,1,1,1,1 +1,0,1,1,1,1,1,0,0 +2,2,2,2,2,2,2,2,2 +2,0,2,0,2,0,0,1,1 +2,2,1,1,2,2,1,3,1 +1,1,2,1,1,1,0,1,0 +1,0,1,1,1,0,1,1,0 +2,2,1,0,1,1,2,2,2 +2,2,2,2,1,1,2,3,1 +1,2,2,2,1,2,2,1,2 +1,0,0,1,1,1,3,2,0 +3,3,2,1,3,1,2,1,2 +0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0 +1,2,1,1,1,1,2,2,1 +3,3,3,3,3,2,3,4,3 +2,2,3,2,2,3,2,2,2 +0,0,0,0,0,1,1,0,0 +2,1,1,2,2,2,1,2,1 +2,2,2,2,1,2,1,2,1 +1,1,3,3,1,1,1,1,1 +2,3,3,3,1,2,4,4,3 +1,2,1,2,2,1,2,2,1 +1,1,2,2,1,2,1,2,1 +0,0,0,0,0,0,0,0,0 +2,1,2,2,2,2,2,2,2 +2,2,1,2,1,2,0,3,0 +0,0,0,0,1,1,0,1,0 +2,1,1,2,2,3,2,2,1 +1,2,3,2,2,0,2,2,0 +2,2,2,1,1,2,1,3,1 +2,2,1,1,1,1,1,3,2 +1,1,2,1,0,2,2,2,1 +2,2,1,2,0,0,0,2,3 +1,1,1,0,0,1,2,3,1 +1,0,0,1,1,1,1,0,0 +2,2,1,1,2,1,2,2,0 +1,1,2,1,1,1,1,1,0 +1,2,2,1,1,0,2,3,1 +1,1,1,1,0,1,1,1,0 +2,2,0,0,2,3,2,4,0 +1,2,3,2,2,0,1,3,1 +1,1,1,1,1,1,1,1,1 +3,2,2,3,2,1,2,2,2 +3,0,0,0,0,0,0,0,0 +0,1,1,0,0,0,1,2,0 +1,1,0,0,2,1,2,1,3 +1,2,0,0,2,0,0,3,2 +0,0,0,0,0,0,0,0,0 +0,2,0,2,3,2,2,2,0 +1,1,2,0,1,1,2,0,2 +2,0,0,0,0,0,2,2,0 +1,1,2,2,2,2,2,2,2 +1,2,2,0,1,0,1,1,0 +2,1,2,1,1,1,1,1,1 +0,1,3,1,1,0,1,3,2 +1,1,1,1,1,0,1,1,1 +2,2,0,0,1,3,3,3,0 +2,2,1,1,2,0,1,2,1 +2,1,1,0,1,1,0,1,1 +0,0,0,0,0,0,0,0,0 +3,3,2,2,4,3,1,4,0 +0,1,1,1,0,1,0,1,0 +1,1,1,1,0,0,1,1,0 +2,2,2,1,2,2,1,2,1 +1,0,2,0,0,0,0,2,0 +1,1,1,1,0,1,0,2,0 +1,2,0,1,2,3,1,2,1 +0,0,2,1,0,0,3,0,0 +1,2,0,1,1,1,1,2,1 +0,0,2,0,2,0,0,0,0 +0,1,0,1,0,0,0,0,0 +2,2,2,3,4,0,2,3,2 +0,1,2,0,0,0,1,2,1 +2,2,2,2,2,2,2,2,2 +2,1,2,1,1,1,0,2,0 +1,0,4,0,0,0,0,0,0 +2,3,2,3,3,0,4,4,3 +2,0,3,1,1,1,0,2,1 +2,2,1,2,2,3,1,4,2 +2,1,0,0,1,2,1,2,1 +1,2,0,0,0,0,2,2,0 +1,3,2,3,2,2,1,3,2 +2,2,1,1,2,1,1,2,2 +1,2,1,2,1,0,2,2,1 +1,1,1,0,1,1,1,1,0 +1,2,2,2,2,2,2,3,0 +1,1,2,1,1,1,2,1,1 +1,2,0,2,2,2,3,3,3 +2,3,4,3,2,0,3,3,2 +0,2,2,1,0,1,1,2,0 +2,2,2,0,0,0,0,3,0 +1,0,0,0,0,0,0,0,0 +2,2,1,1,2,2,1,2,2 +1,2,4,1,2,3,4,3,2 +2,2,0,2,2,2,2,2,1 +0,2,0,0,0,0,0,2,0 +2,2,2,2,1,1,2,3,1 +1,1,1,0,1,1,1,2,1 +2,2,1,1,0,1,2,3,1 +1,1,1,1,2,2,1,2,0 +2,1,0,0,1,0,1,1,0 +1,1,1,0,1,1,1,1,0 +2,2,2,2,2,2,2,2,2 +2,1,1,1,1,2,1,2,1 +1,1,2,1,2,1,1,0,1 +2,3,2,1,0,1,0,3,0 +1,1,1,0,1,2,0,2,0 +0,0,0,0,0,0,0,0,0 +2,2,2,1,2,1,2,2,1 +1,0,0,0,1,0,0,1,0 +1,1,0,0,0,0,0,1,0 \ No newline at end of file diff --git a/Resources/Data Sets/Data Library/13. Reliability/ADD symptoms.jasp b/Resources/Data Sets/Data Library/13. Reliability/ADD symptoms.jasp new file mode 100644 index 0000000000..2294ef7184 Binary files /dev/null and b/Resources/Data Sets/Data Library/13. Reliability/ADD symptoms.jasp differ diff --git a/Resources/Data Sets/Data Library/14. SEM/Grand Point Average.jasp b/Resources/Data Sets/Data Library/14. SEM/Grand Point Average.jasp index f887900f59..bbfc5dbd09 100644 Binary files a/Resources/Data Sets/Data Library/14. SEM/Grand Point Average.jasp and b/Resources/Data Sets/Data Library/14. SEM/Grand Point Average.jasp differ diff --git a/Resources/Data Sets/Data Library/14. SEM/Political Democracy.jasp b/Resources/Data Sets/Data Library/14. SEM/Political Democracy.jasp index a3f2d6f9ce..f9080dbc6b 100644 Binary files a/Resources/Data Sets/Data Library/14. SEM/Political Democracy.jasp and b/Resources/Data Sets/Data Library/14. SEM/Political Democracy.jasp differ diff --git a/Resources/Data Sets/index.json b/Resources/Data Sets/index.json index d58350a5a7..5e2a1edd03 100644 --- a/Resources/Data Sets/index.json +++ b/Resources/Data Sets/index.json @@ -847,6 +847,13 @@ "description": "Hypothetical data set from a paper on ICCs by Shrout and Fleiss (1979). The file demonstrates the use of classical intraclass correlation coefficients", "kind": "file", "associated_datafile": "Interrater Data from Shrout and Fleiss (1979).csv" + }, + { + "name": "ADD symptoms", + "path": "ADD symptoms.jasp", + "description": "The data sample consists of children (N=1162) who were rated by their parents on nine 5-point Likert-scale (0-4) items about attention deficit disorder (ADD) symptoms (Keulers & Hurks, 2021). The ordered response categories, 0, 1, 2, 3, and 4 represent the prevalence of a specific symptomatic behavior, ranging from 0 (never) to 4 (very often). For the ADD scale, a higher sum score indicates more ADHD symptoms. The file demonstrates the use of the score-related standard error of measurement.", + "kind": "file", + "associated_datafile": "ADD symptoms.csv" } ], "debug": false diff --git a/Resources/Data Sets/index_de.json b/Resources/Data Sets/index_de.json index ddba6db0ad..46fc836a79 100644 --- a/Resources/Data Sets/index_de.json +++ b/Resources/Data Sets/index_de.json @@ -847,6 +847,13 @@ "description": "Hypothetischer Datensatz aus einer Arbeit über ICCs von Shrout und Fleiss (1979). Die Datei demonstriert die Verwendung der klassischen Intraklassen-Korrelationskoeffizienten", "kind": "file", "associated_datafile": "Interrater Data from Shrout and Fleiss (1979).csv" + }, + { + "name": "ADS symptoms", + "path": "ADD symptoms.jasp", + "description": "Die Stichprobe besteht aus Kindern (N=1162), die von ihren Eltern anhand von neun 5-Punkte-Likert-Skala (0-4) Items zu Symptomen der Aufmerksamkeitsdefizitstörung (ADS) bewertet wurden (Keulers & Hurks, 2021). Die geordneten Antwortkategorien 0, 1, 2, 3 und 4 repräsentieren das Auftreten eines spezifischen symptomatischen Verhaltens, wobei 0 (nie) und 4 (sehr oft) bedeuten. Für die ADD-Skala weist eine höhere Summe der Punktzahlen auf mehr ADS-Symptome hin. Die Datei zeigt die Verwendung des Score-bezogenen Standardfehlers der Messung.", + "kind": "file", + "associated_datafile": "ADD symptoms.csv" } ], "debug": false diff --git a/Resources/Data Sets/index_nl.json b/Resources/Data Sets/index_nl.json index e7290a0967..e25f4dbfde 100644 --- a/Resources/Data Sets/index_nl.json +++ b/Resources/Data Sets/index_nl.json @@ -847,6 +847,13 @@ "description": "Hypothetische dataset uit een artikel over ICC's van Shrout en Fleiss (1979). Het bestand demonstreert het gebruik van klassieke intra-klasse correlatiecoëfficiënten", "kind": "file", "associated_datafile": "Interrater Data from Shrout and Fleiss (1979).csv" + }, + { + "name": "ADD symptomen", + "path": "ADD symptoms.jasp", + "description": "De steekproef bestaat uit kinderen (N=1162) die door hun ouders zijn beoordeeld op negen 5-punt Likert-schaal (0-4) items met betrekking tot symptomen van Attention Deficit Disorder (ADD) (Keulers & Hurks, 2021). De geordende antwoordcategorieën 0, 1, 2, 3 en 4 vertegenwoordigen de frequentie van specifiek symptomatisch gedrag, waarbij 0 (nooit) en 4 (zeer vaak) betekenen. Voor de ADD-schaal duidt een hogere somscore op meer ADD-symptomen. Het bestand toont het gebruik van de score-gerelateerde standaardfout van de meting.", + "kind": "file", + "associated_datafile": "ADD symptoms.csv" } ], "debug": false diff --git a/Resources/Data Sets/index_zh_Hans.json b/Resources/Data Sets/index_zh_Hans.json index 08bca595bf..35c118e7e4 100644 --- a/Resources/Data Sets/index_zh_Hans.json +++ b/Resources/Data Sets/index_zh_Hans.json @@ -847,6 +847,13 @@ "description": "来自 Shrout 和 Fleiss (1979) 关于 ICC 的论文的假设数据集。 该文件演示了经典类内相关系数的使用", "kind": "file", "associated_datafile": "Interrater Data from Shrout and Fleiss (1979).csv" + }, + { + "name": "Add symptoms", + "path": "ADD symptoms.jasp", + "description": "数据样本由儿童(N=1163)的注意力缺陷障碍 (ADD) 症状进行评分构成,他们按照根据九个5分制李克特量表 (0-4)进行了打分( Keulers & Hurks, 2021)。有序响应类别 0、1、2、3 、 4 表示特定症状行为的普遍性,范围从 0(从不)到 4(非常频繁)。对于 ADD 量表,总分越高,ADHD 症状越明显。该文件演示了分数相关标准测量误差的使用。", + "kind": "file", + "associated_datafile": "ADD symptoms.csv" } ], "debug": false @@ -1154,4 +1161,4 @@ } ] } - \ No newline at end of file + diff --git a/Resources/Help/marked-hljs-ext.js b/Resources/Help/marked-hljs-ext.js index 8979915c53..c4996ebf88 100644 --- a/Resources/Help/marked-hljs-ext.js +++ b/Resources/Help/marked-hljs-ext.js @@ -1,9 +1,10 @@ /** - * Edit from marked-highlight at 2023-06-01 + * Edit from marked-highlight at 2024-08-04 * MIT Licensed * https://github.com/markedjs/marked-highlight */ -function markedHighlight(options) { + + function markedHighlight(options) { if (typeof options === 'function') { options = { highlight: options @@ -25,18 +26,28 @@ function markedHighlight(options) { return; } - const lang = getLang(token); + const lang = getLang(token.lang); if (options.async) { - return Promise.resolve(options.highlight(token.text, lang)).then(updateToken(token)); + return Promise.resolve(options.highlight(token.text, lang, token.lang || '')).then(updateToken(token)); } - const code = options.highlight(token.text, lang); + const code = options.highlight(token.text, lang, token.lang || ''); + if (code instanceof Promise) { + throw new Error('markedHighlight is not set to async but the highlight function is async. Set the async option to true on markedHighlight to await the async highlight function.'); + } updateToken(token)(code); }, + useNewRenderer: true, renderer: { code(code, infoString, escaped) { - const lang = (infoString || '').match(/\S*/)[0]; + // istanbul ignore next + if (typeof code === 'object') { + escaped = code.escaped; + infoString = code.lang; + code = code.text; + } + const lang = getLang(infoString); const classAttr = lang ? ` class="${options.langPrefix}${escape(lang)}"` : ''; @@ -47,8 +58,8 @@ function markedHighlight(options) { }; } - function getLang(token) { - return (token.lang || '').match(/\S*/)[0]; + function getLang(lang) { + return (lang || '').match(/\S*/)[0]; } function updateToken(token) { diff --git a/Resources/Help/marked.js b/Resources/Help/marked.js index d135da23cf..beafbda8c5 100644 --- a/Resources/Help/marked.js +++ b/Resources/Help/marked.js @@ -1,6 +1,6 @@ /** - * marked v5.0.1 - a markdown parser - * Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed) + * marked v13.0.3 - a markdown parser + * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed) * https://github.com/markedjs/marked */ @@ -15,2816 +15,2712 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.marked = {})); })(this, (function (exports) { 'use strict'; - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); - } - } - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - Object.defineProperty(Constructor, "prototype", { - writable: false - }); - return Constructor; - } - function _extends() { - _extends = Object.assign ? Object.assign.bind() : function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } - function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); - } - function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; - for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; - return arr2; - } - function _createForOfIteratorHelperLoose(o, allowArrayLike) { - var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; - if (it) return (it = it.call(o)).next.bind(it); - if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { - if (it) o = it; - var i = 0; - return function () { - if (i >= o.length) return { - done: true - }; - return { - done: false, - value: o[i++] - }; + /** + * Gets the original marked default options. + */ + function _getDefaults() { + return { + async: false, + breaks: false, + extensions: null, + gfm: true, + hooks: null, + pedantic: false, + renderer: null, + silent: false, + tokenizer: null, + walkTokens: null, }; - } - throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); - } - function _toPrimitive(input, hint) { - if (typeof input !== "object" || input === null) return input; - var prim = input[Symbol.toPrimitive]; - if (prim !== undefined) { - var res = prim.call(input, hint || "default"); - if (typeof res !== "object") return res; - throw new TypeError("@@toPrimitive must return a primitive value."); - } - return (hint === "string" ? String : Number)(input); } - function _toPropertyKey(arg) { - var key = _toPrimitive(arg, "string"); - return typeof key === "symbol" ? key : String(key); - } - - function getDefaults() { - return { - async: false, - baseUrl: null, - breaks: false, - extensions: null, - gfm: true, - headerIds: true, - headerPrefix: '', - highlight: null, - hooks: null, - langPrefix: 'language-', - mangle: true, - pedantic: false, - renderer: null, - sanitize: false, - sanitizer: null, - silent: false, - smartypants: false, - tokenizer: null, - walkTokens: null, - xhtml: false - }; - } - exports.defaults = getDefaults(); + exports.defaults = _getDefaults(); function changeDefaults(newDefaults) { - exports.defaults = newDefaults; + exports.defaults = newDefaults; } /** * Helpers */ - var escapeTest = /[&<>"']/; - var escapeReplace = new RegExp(escapeTest.source, 'g'); - var escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/; - var escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g'); - var escapeReplacements = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - var getEscapeReplacement = function getEscapeReplacement(ch) { - return escapeReplacements[ch]; + const escapeTest = /[&<>"']/; + const escapeReplace = new RegExp(escapeTest.source, 'g'); + const escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/; + const escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g'); + const escapeReplacements = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', }; - function escape(html, encode) { - if (encode) { - if (escapeTest.test(html)) { - return html.replace(escapeReplace, getEscapeReplacement); + const getEscapeReplacement = (ch) => escapeReplacements[ch]; + function escape$1(html, encode) { + if (encode) { + if (escapeTest.test(html)) { + return html.replace(escapeReplace, getEscapeReplacement); + } } - } else { - if (escapeTestNoEncode.test(html)) { - return html.replace(escapeReplaceNoEncode, getEscapeReplacement); + else { + if (escapeTestNoEncode.test(html)) { + return html.replace(escapeReplaceNoEncode, getEscapeReplacement); + } } - } - return html; + return html; } - var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; - - /** - * @param {string} html - */ + const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; function unescape(html) { - // explicitly match decimal, hex, and named HTML entities - return html.replace(unescapeTest, function (_, n) { - n = n.toLowerCase(); - if (n === 'colon') return ':'; - if (n.charAt(0) === '#') { - return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1)); - } - return ''; - }); + // explicitly match decimal, hex, and named HTML entities + return html.replace(unescapeTest, (_, n) => { + n = n.toLowerCase(); + if (n === 'colon') + return ':'; + if (n.charAt(0) === '#') { + return n.charAt(1) === 'x' + ? String.fromCharCode(parseInt(n.substring(2), 16)) + : String.fromCharCode(+n.substring(1)); + } + return ''; + }); } - var caret = /(^|[^\[])\^/g; - - /** - * @param {string | RegExp} regex - * @param {string} opt - */ + const caret = /(^|[^\[])\^/g; function edit(regex, opt) { - regex = typeof regex === 'string' ? regex : regex.source; - opt = opt || ''; - var obj = { - replace: function replace(name, val) { - val = val.source || val; - val = val.replace(caret, '$1'); - regex = regex.replace(name, val); - return obj; - }, - getRegex: function getRegex() { - return new RegExp(regex, opt); - } - }; - return obj; + let source = typeof regex === 'string' ? regex : regex.source; + opt = opt || ''; + const obj = { + replace: (name, val) => { + let valSource = typeof val === 'string' ? val : val.source; + valSource = valSource.replace(caret, '$1'); + source = source.replace(name, valSource); + return obj; + }, + getRegex: () => { + return new RegExp(source, opt); + }, + }; + return obj; } - var nonWordAndColonTest = /[^\w:]/g; - var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; - - /** - * @param {boolean} sanitize - * @param {string} base - * @param {string} href - */ - function cleanUrl(sanitize, base, href) { - if (sanitize) { - var prot; + function cleanUrl(href) { try { - prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, '').toLowerCase(); - } catch (e) { - return null; - } - if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) { - return null; - } - } - if (base && !originIndependentUrl.test(href)) { - href = resolveUrl(base, href); - } - try { - href = encodeURI(href).replace(/%25/g, '%'); - } catch (e) { - return null; - } - return href; - } - var baseUrls = {}; - var justDomain = /^[^:]+:\/*[^/]*$/; - var protocol = /^([^:]+:)[\s\S]*$/; - var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; - - /** - * @param {string} base - * @param {string} href - */ - function resolveUrl(base, href) { - if (!baseUrls[' ' + base]) { - // we can ignore everything in base after the last slash of its path component, - // but we might need to add _that_ - // https://tools.ietf.org/html/rfc3986#section-3 - if (justDomain.test(base)) { - baseUrls[' ' + base] = base + '/'; - } else { - baseUrls[' ' + base] = rtrim(base, '/', true); - } - } - base = baseUrls[' ' + base]; - var relativeBase = base.indexOf(':') === -1; - if (href.substring(0, 2) === '//') { - if (relativeBase) { - return href; - } - return base.replace(protocol, '$1') + href; - } else if (href.charAt(0) === '/') { - if (relativeBase) { - return href; - } - return base.replace(domain, '$1') + href; - } else { - return base + href; - } + href = encodeURI(href).replace(/%25/g, '%'); + } + catch { + return null; + } + return href; } - var noopTest = { - exec: function noopTest() {} - }; + const noopTest = { exec: () => null }; function splitCells(tableRow, count) { - // ensure that every cell-delimiting pipe has a space - // before it to distinguish it from an escaped pipe - var row = tableRow.replace(/\|/g, function (match, offset, str) { - var escaped = false, - curr = offset; - while (--curr >= 0 && str[curr] === '\\') escaped = !escaped; - if (escaped) { - // odd number of slashes means | is escaped - // so we leave it alone - return '|'; - } else { - // add space before unescaped | - return ' |'; - } - }), - cells = row.split(/ \|/); - var i = 0; - - // First/last cell in a row cannot be empty if it has no leading/trailing pipe - if (!cells[0].trim()) { - cells.shift(); - } - if (cells.length > 0 && !cells[cells.length - 1].trim()) { - cells.pop(); - } - if (cells.length > count) { - cells.splice(count); - } else { - while (cells.length < count) cells.push(''); - } - for (; i < cells.length; i++) { - // leading or trailing whitespace is ignored per the gfm spec - cells[i] = cells[i].trim().replace(/\\\|/g, '|'); - } - return cells; + // ensure that every cell-delimiting pipe has a space + // before it to distinguish it from an escaped pipe + const row = tableRow.replace(/\|/g, (match, offset, str) => { + let escaped = false; + let curr = offset; + while (--curr >= 0 && str[curr] === '\\') + escaped = !escaped; + if (escaped) { + // odd number of slashes means | is escaped + // so we leave it alone + return '|'; + } + else { + // add space before unescaped | + return ' |'; + } + }), cells = row.split(/ \|/); + let i = 0; + // First/last cell in a row cannot be empty if it has no leading/trailing pipe + if (!cells[0].trim()) { + cells.shift(); + } + if (cells.length > 0 && !cells[cells.length - 1].trim()) { + cells.pop(); + } + if (count) { + if (cells.length > count) { + cells.splice(count); + } + else { + while (cells.length < count) + cells.push(''); + } + } + for (; i < cells.length; i++) { + // leading or trailing whitespace is ignored per the gfm spec + cells[i] = cells[i].trim().replace(/\\\|/g, '|'); + } + return cells; } - /** * Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). * /c*$/ is vulnerable to REDOS. * - * @param {string} str - * @param {string} c - * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey. + * @param str + * @param c + * @param invert Remove suffix of non-c chars instead. Default falsey. */ function rtrim(str, c, invert) { - var l = str.length; - if (l === 0) { - return ''; - } - - // Length of suffix matching the invert condition. - var suffLen = 0; - - // Step left until we fail to match the invert condition. - while (suffLen < l) { - var currChar = str.charAt(l - suffLen - 1); - if (currChar === c && !invert) { - suffLen++; - } else if (currChar !== c && invert) { - suffLen++; - } else { - break; - } - } - return str.slice(0, l - suffLen); + const l = str.length; + if (l === 0) { + return ''; + } + // Length of suffix matching the invert condition. + let suffLen = 0; + // Step left until we fail to match the invert condition. + while (suffLen < l) { + const currChar = str.charAt(l - suffLen - 1); + if (currChar === c && !invert) { + suffLen++; + } + else if (currChar !== c && invert) { + suffLen++; + } + else { + break; + } + } + return str.slice(0, l - suffLen); } function findClosingBracket(str, b) { - if (str.indexOf(b[1]) === -1) { + if (str.indexOf(b[1]) === -1) { + return -1; + } + let level = 0; + for (let i = 0; i < str.length; i++) { + if (str[i] === '\\') { + i++; + } + else if (str[i] === b[0]) { + level++; + } + else if (str[i] === b[1]) { + level--; + if (level < 0) { + return i; + } + } + } return -1; - } - var l = str.length; - var level = 0, - i = 0; - for (; i < l; i++) { - if (str[i] === '\\') { - i++; - } else if (str[i] === b[0]) { - level++; - } else if (str[i] === b[1]) { - level--; - if (level < 0) { - return i; - } - } - } - return -1; - } - function checkDeprecations(opt, callback) { - if (!opt || opt.silent) { - return; - } - if (callback) { - console.warn('marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async'); - } - if (opt.sanitize || opt.sanitizer) { - console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options'); - } - if (opt.highlight || opt.langPrefix !== 'language-') { - console.warn('marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight.'); - } - if (opt.mangle) { - console.warn('marked(): mangle parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-mangle.'); - } - if (opt.baseUrl) { - console.warn('marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url.'); - } - if (opt.smartypants) { - console.warn('marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants.'); - } - if (opt.xhtml) { - console.warn('marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml.'); - } - if (opt.headerIds || opt.headerPrefix) { - console.warn('marked(): headerIds and headerPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-gfm-heading-id.'); - } - } - - // copied from https://stackoverflow.com/a/5450113/806777 - /** - * @param {string} pattern - * @param {number} count - */ - function repeatString(pattern, count) { - if (count < 1) { - return ''; - } - var result = ''; - while (count > 1) { - if (count & 1) { - result += pattern; - } - count >>= 1; - pattern += pattern; - } - return result + pattern; } function outputLink(cap, link, raw, lexer) { - var href = link.href; - var title = link.title ? escape(link.title) : null; - var text = cap[1].replace(/\\([\[\]])/g, '$1'); - if (cap[0].charAt(0) !== '!') { - lexer.state.inLink = true; - var token = { - type: 'link', - raw: raw, - href: href, - title: title, - text: text, - tokens: lexer.inlineTokens(text) + const href = link.href; + const title = link.title ? escape$1(link.title) : null; + const text = cap[1].replace(/\\([\[\]])/g, '$1'); + if (cap[0].charAt(0) !== '!') { + lexer.state.inLink = true; + const token = { + type: 'link', + raw, + href, + title, + text, + tokens: lexer.inlineTokens(text), + }; + lexer.state.inLink = false; + return token; + } + return { + type: 'image', + raw, + href, + title, + text: escape$1(text), }; - lexer.state.inLink = false; - return token; - } - return { - type: 'image', - raw: raw, - href: href, - title: title, - text: escape(text) - }; } function indentCodeCompensation(raw, text) { - var matchIndentToCode = raw.match(/^(\s+)(?:```)/); - if (matchIndentToCode === null) { - return text; - } - var indentToCode = matchIndentToCode[1]; - return text.split('\n').map(function (node) { - var matchIndentInNode = node.match(/^\s+/); - if (matchIndentInNode === null) { - return node; - } - var indentInNode = matchIndentInNode[0]; - if (indentInNode.length >= indentToCode.length) { - return node.slice(indentToCode.length); - } - return node; - }).join('\n'); + const matchIndentToCode = raw.match(/^(\s+)(?:```)/); + if (matchIndentToCode === null) { + return text; + } + const indentToCode = matchIndentToCode[1]; + return text + .split('\n') + .map(node => { + const matchIndentInNode = node.match(/^\s+/); + if (matchIndentInNode === null) { + return node; + } + const [indentInNode] = matchIndentInNode; + if (indentInNode.length >= indentToCode.length) { + return node.slice(indentToCode.length); + } + return node; + }) + .join('\n'); } - /** * Tokenizer */ - var Tokenizer = /*#__PURE__*/function () { - function Tokenizer(options) { - this.options = options || exports.defaults; - } - var _proto = Tokenizer.prototype; - _proto.space = function space(src) { - var cap = this.rules.block.newline.exec(src); - if (cap && cap[0].length > 0) { - return { - type: 'space', - raw: cap[0] - }; - } - }; - _proto.code = function code(src) { - var cap = this.rules.block.code.exec(src); - if (cap) { - var text = cap[0].replace(/^ {1,4}/gm, ''); - return { - type: 'code', - raw: cap[0], - codeBlockStyle: 'indented', - text: !this.options.pedantic ? rtrim(text, '\n') : text - }; - } - }; - _proto.fences = function fences(src) { - var cap = this.rules.block.fences.exec(src); - if (cap) { - var raw = cap[0]; - var text = indentCodeCompensation(raw, cap[3] || ''); - return { - type: 'code', - raw: raw, - lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2], - text: text - }; - } - }; - _proto.heading = function heading(src) { - var cap = this.rules.block.heading.exec(src); - if (cap) { - var text = cap[2].trim(); - - // remove trailing #s - if (/#$/.test(text)) { - var trimmed = rtrim(text, '#'); - if (this.options.pedantic) { - text = trimmed.trim(); - } else if (!trimmed || / $/.test(trimmed)) { - // CommonMark requires space before trailing #s - text = trimmed.trim(); - } - } - return { - type: 'heading', - raw: cap[0], - depth: cap[1].length, - text: text, - tokens: this.lexer.inline(text) - }; - } - }; - _proto.hr = function hr(src) { - var cap = this.rules.block.hr.exec(src); - if (cap) { - return { - type: 'hr', - raw: cap[0] - }; - } - }; - _proto.blockquote = function blockquote(src) { - var cap = this.rules.block.blockquote.exec(src); - if (cap) { - var text = cap[0].replace(/^ *>[ \t]?/gm, ''); - var top = this.lexer.state.top; - this.lexer.state.top = true; - var tokens = this.lexer.blockTokens(text); - this.lexer.state.top = top; - return { - type: 'blockquote', - raw: cap[0], - tokens: tokens, - text: text - }; - } - }; - _proto.list = function list(src) { - var cap = this.rules.block.list.exec(src); - if (cap) { - var raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly; - var bull = cap[1].trim(); - var isordered = bull.length > 1; - var list = { - type: 'list', - raw: '', - ordered: isordered, - start: isordered ? +bull.slice(0, -1) : '', - loose: false, - items: [] - }; - bull = isordered ? "\\d{1,9}\\" + bull.slice(-1) : "\\" + bull; - if (this.options.pedantic) { - bull = isordered ? bull : '[*+-]'; - } - - // Get next list item - var itemRegex = new RegExp("^( {0,3}" + bull + ")((?:[\t ][^\\n]*)?(?:\\n|$))"); - - // Check if current bullet point can start a new List Item - while (src) { - endEarly = false; - if (!(cap = itemRegex.exec(src))) { - break; - } - if (this.rules.block.hr.test(src)) { - // End list if bullet was actually HR (possibly move into itemRegex?) - break; - } - raw = cap[0]; - src = src.substring(raw.length); - line = cap[2].split('\n', 1)[0].replace(/^\t+/, function (t) { - return ' '.repeat(3 * t.length); - }); - nextLine = src.split('\n', 1)[0]; - if (this.options.pedantic) { - indent = 2; - itemContents = line.trimLeft(); - } else { - indent = cap[2].search(/[^ ]/); // Find first non-space char - indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent - itemContents = line.slice(indent); - indent += cap[1].length; - } - blankLine = false; - if (!line && /^ *$/.test(nextLine)) { - // Items begin with at most one blank line - raw += nextLine + '\n'; - src = src.substring(nextLine.length + 1); - endEarly = true; - } - if (!endEarly) { - var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))"); - var hrRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)"); - var fencesBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:```|~~~)"); - var headingBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}#"); - - // Check if following lines should be included in List Item - while (src) { - rawLine = src.split('\n', 1)[0]; - nextLine = rawLine; - - // Re-align to follow commonmark nesting rules + class _Tokenizer { + options; + rules; // set by the lexer + lexer; // set by the lexer + constructor(options) { + this.options = options || exports.defaults; + } + space(src) { + const cap = this.rules.block.newline.exec(src); + if (cap && cap[0].length > 0) { + return { + type: 'space', + raw: cap[0], + }; + } + } + code(src) { + const cap = this.rules.block.code.exec(src); + if (cap) { + const text = cap[0].replace(/^ {1,4}/gm, ''); + return { + type: 'code', + raw: cap[0], + codeBlockStyle: 'indented', + text: !this.options.pedantic + ? rtrim(text, '\n') + : text, + }; + } + } + fences(src) { + const cap = this.rules.block.fences.exec(src); + if (cap) { + const raw = cap[0]; + const text = indentCodeCompensation(raw, cap[3] || ''); + return { + type: 'code', + raw, + lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2], + text, + }; + } + } + heading(src) { + const cap = this.rules.block.heading.exec(src); + if (cap) { + let text = cap[2].trim(); + // remove trailing #s + if (/#$/.test(text)) { + const trimmed = rtrim(text, '#'); + if (this.options.pedantic) { + text = trimmed.trim(); + } + else if (!trimmed || / $/.test(trimmed)) { + // CommonMark requires space before trailing #s + text = trimmed.trim(); + } + } + return { + type: 'heading', + raw: cap[0], + depth: cap[1].length, + text, + tokens: this.lexer.inline(text), + }; + } + } + hr(src) { + const cap = this.rules.block.hr.exec(src); + if (cap) { + return { + type: 'hr', + raw: rtrim(cap[0], '\n'), + }; + } + } + blockquote(src) { + const cap = this.rules.block.blockquote.exec(src); + if (cap) { + let lines = rtrim(cap[0], '\n').split('\n'); + let raw = ''; + let text = ''; + const tokens = []; + while (lines.length > 0) { + let inBlockquote = false; + const currentLines = []; + let i; + for (i = 0; i < lines.length; i++) { + // get lines up to a continuation + if (/^ {0,3}>/.test(lines[i])) { + currentLines.push(lines[i]); + inBlockquote = true; + } + else if (!inBlockquote) { + currentLines.push(lines[i]); + } + else { + break; + } + } + lines = lines.slice(i); + const currentRaw = currentLines.join('\n'); + const currentText = currentRaw + // precede setext continuation with 4 spaces so it isn't a setext + .replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g, '\n $1') + .replace(/^ {0,3}>[ \t]?/gm, ''); + raw = raw ? `${raw}\n${currentRaw}` : currentRaw; + text = text ? `${text}\n${currentText}` : currentText; + // parse blockquote lines as top level tokens + // merge paragraphs if this is a continuation + const top = this.lexer.state.top; + this.lexer.state.top = true; + this.lexer.blockTokens(currentText, tokens, true); + this.lexer.state.top = top; + // if there is no continuation then we are done + if (lines.length === 0) { + break; + } + const lastToken = tokens[tokens.length - 1]; + if (lastToken?.type === 'code') { + // blockquote continuation cannot be preceded by a code block + break; + } + else if (lastToken?.type === 'blockquote') { + // include continuation in nested blockquote + const oldToken = lastToken; + const newText = oldToken.raw + '\n' + lines.join('\n'); + const newToken = this.blockquote(newText); + tokens[tokens.length - 1] = newToken; + raw = raw.substring(0, raw.length - oldToken.raw.length) + newToken.raw; + text = text.substring(0, text.length - oldToken.text.length) + newToken.text; + break; + } + else if (lastToken?.type === 'list') { + // include continuation in nested list + const oldToken = lastToken; + const newText = oldToken.raw + '\n' + lines.join('\n'); + const newToken = this.list(newText); + tokens[tokens.length - 1] = newToken; + raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw; + text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw; + lines = newText.substring(tokens[tokens.length - 1].raw.length).split('\n'); + continue; + } + } + return { + type: 'blockquote', + raw, + tokens, + text, + }; + } + } + list(src) { + let cap = this.rules.block.list.exec(src); + if (cap) { + let bull = cap[1].trim(); + const isordered = bull.length > 1; + const list = { + type: 'list', + raw: '', + ordered: isordered, + start: isordered ? +bull.slice(0, -1) : '', + loose: false, + items: [], + }; + bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`; if (this.options.pedantic) { - nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); + bull = isordered ? bull : '[*+-]'; } - - // End list item if found code fences - if (fencesBeginRegex.test(nextLine)) { - break; + // Get next list item + const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`); + let endsWithBlankLine = false; + // Check if current bullet point can start a new List Item + while (src) { + let endEarly = false; + let raw = ''; + let itemContents = ''; + if (!(cap = itemRegex.exec(src))) { + break; + } + if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?) + break; + } + raw = cap[0]; + src = src.substring(raw.length); + let line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length)); + let nextLine = src.split('\n', 1)[0]; + let blankLine = !line.trim(); + let indent = 0; + if (this.options.pedantic) { + indent = 2; + itemContents = line.trimStart(); + } + else if (blankLine) { + indent = cap[1].length + 1; + } + else { + indent = cap[2].search(/[^ ]/); // Find first non-space char + indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent + itemContents = line.slice(indent); + indent += cap[1].length; + } + if (blankLine && /^ *$/.test(nextLine)) { // Items begin with at most one blank line + raw += nextLine + '\n'; + src = src.substring(nextLine.length + 1); + endEarly = true; + } + if (!endEarly) { + const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`); + const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`); + const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`); + const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`); + // Check if following lines should be included in List Item + while (src) { + const rawLine = src.split('\n', 1)[0]; + nextLine = rawLine; + // Re-align to follow commonmark nesting rules + if (this.options.pedantic) { + nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); + } + // End list item if found code fences + if (fencesBeginRegex.test(nextLine)) { + break; + } + // End list item if found start of new heading + if (headingBeginRegex.test(nextLine)) { + break; + } + // End list item if found start of new bullet + if (nextBulletRegex.test(nextLine)) { + break; + } + // Horizontal rule found + if (hrRegex.test(src)) { + break; + } + if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible + itemContents += '\n' + nextLine.slice(indent); + } + else { + // not enough indentation + if (blankLine) { + break; + } + // paragraph continuation unless last line was a different block level element + if (line.search(/[^ ]/) >= 4) { // indented code block + break; + } + if (fencesBeginRegex.test(line)) { + break; + } + if (headingBeginRegex.test(line)) { + break; + } + if (hrRegex.test(line)) { + break; + } + itemContents += '\n' + nextLine; + } + if (!blankLine && !nextLine.trim()) { // Check if current line is blank + blankLine = true; + } + raw += rawLine + '\n'; + src = src.substring(rawLine.length + 1); + line = nextLine.slice(indent); + } + } + if (!list.loose) { + // If the previous item ended with a blank line, the list is loose + if (endsWithBlankLine) { + list.loose = true; + } + else if (/\n *\n *$/.test(raw)) { + endsWithBlankLine = true; + } + } + let istask = null; + let ischecked; + // Check for task list items + if (this.options.gfm) { + istask = /^\[[ xX]\] /.exec(itemContents); + if (istask) { + ischecked = istask[0] !== '[ ] '; + itemContents = itemContents.replace(/^\[[ xX]\] +/, ''); + } + } + list.items.push({ + type: 'list_item', + raw, + task: !!istask, + checked: ischecked, + loose: false, + text: itemContents, + tokens: [], + }); + list.raw += raw; } - - // End list item if found start of new heading - if (headingBeginRegex.test(nextLine)) { - break; + // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic + list.items[list.items.length - 1].raw = list.items[list.items.length - 1].raw.trimEnd(); + list.items[list.items.length - 1].text = list.items[list.items.length - 1].text.trimEnd(); + list.raw = list.raw.trimEnd(); + // Item child tokens handled here at end because we needed to have the final item to trim it first + for (let i = 0; i < list.items.length; i++) { + this.lexer.state.top = false; + list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []); + if (!list.loose) { + // Check if list should be loose + const spacers = list.items[i].tokens.filter(t => t.type === 'space'); + const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw)); + list.loose = hasMultipleLineBreaks; + } } - - // End list item if found start of new bullet - if (nextBulletRegex.test(nextLine)) { - break; + // Set all items to loose if list is loose + if (list.loose) { + for (let i = 0; i < list.items.length; i++) { + list.items[i].loose = true; + } } - - // Horizontal rule found - if (hrRegex.test(src)) { - break; - } - if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { - // Dedent if possible - itemContents += '\n' + nextLine.slice(indent); - } else { - // not enough indentation - if (blankLine) { - break; - } - - // paragraph continuation unless last line was a different block level element - if (line.search(/[^ ]/) >= 4) { - // indented code block - break; - } - if (fencesBeginRegex.test(line)) { - break; - } - if (headingBeginRegex.test(line)) { - break; - } - if (hrRegex.test(line)) { - break; - } - itemContents += '\n' + nextLine; - } - if (!blankLine && !nextLine.trim()) { - // Check if current line is blank - blankLine = true; - } - raw += rawLine + '\n'; - src = src.substring(rawLine.length + 1); - line = nextLine.slice(indent); - } - } - if (!list.loose) { - // If the previous item ended with a blank line, the list is loose - if (endsWithBlankLine) { - list.loose = true; - } else if (/\n *\n *$/.test(raw)) { - endsWithBlankLine = true; - } + return list; } - - // Check for task list items - if (this.options.gfm) { - istask = /^\[[ xX]\] /.exec(itemContents); - if (istask) { - ischecked = istask[0] !== '[ ] '; - itemContents = itemContents.replace(/^\[[ xX]\] +/, ''); - } - } - list.items.push({ - type: 'list_item', - raw: raw, - task: !!istask, - checked: ischecked, - loose: false, - text: itemContents - }); - list.raw += raw; - } - - // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic - list.items[list.items.length - 1].raw = raw.trimRight(); - list.items[list.items.length - 1].text = itemContents.trimRight(); - list.raw = list.raw.trimRight(); - var l = list.items.length; - - // Item child tokens handled here at end because we needed to have the final item to trim it first - for (i = 0; i < l; i++) { - this.lexer.state.top = false; - list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []); - if (!list.loose) { - // Check if list should be loose - var spacers = list.items[i].tokens.filter(function (t) { - return t.type === 'space'; - }); - var hasMultipleLineBreaks = spacers.length > 0 && spacers.some(function (t) { - return /\n.*\n/.test(t.raw); - }); - list.loose = hasMultipleLineBreaks; - } - } - - // Set all items to loose if list is loose - if (list.loose) { - for (i = 0; i < l; i++) { - list.items[i].loose = true; - } - } - return list; - } - }; - _proto.html = function html(src) { - var cap = this.rules.block.html.exec(src); - if (cap) { - var token = { - type: 'html', - block: true, - raw: cap[0], - pre: !this.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), - text: cap[0] - }; - if (this.options.sanitize) { - var text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]); - token.type = 'paragraph'; - token.text = text; - token.tokens = this.lexer.inline(text); - } - return token; - } - }; - _proto.def = function def(src) { - var cap = this.rules.block.def.exec(src); - if (cap) { - var tag = cap[1].toLowerCase().replace(/\s+/g, ' '); - var href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : ''; - var title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3]; - return { - type: 'def', - tag: tag, - raw: cap[0], - href: href, - title: title - }; - } - }; - _proto.table = function table(src) { - var cap = this.rules.block.table.exec(src); - if (cap) { - var item = { - type: 'table', - header: splitCells(cap[1]).map(function (c) { - return { - text: c - }; - }), - align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), - rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [] - }; - if (item.header.length === item.align.length) { - item.raw = cap[0]; - var l = item.align.length; - var i, j, k, row; - for (i = 0; i < l; i++) { - if (/^ *-+: *$/.test(item.align[i])) { - item.align[i] = 'right'; - } else if (/^ *:-+: *$/.test(item.align[i])) { - item.align[i] = 'center'; - } else if (/^ *:-+ *$/.test(item.align[i])) { - item.align[i] = 'left'; - } else { - item.align[i] = null; - } - } - l = item.rows.length; - for (i = 0; i < l; i++) { - item.rows[i] = splitCells(item.rows[i], item.header.length).map(function (c) { + } + html(src) { + const cap = this.rules.block.html.exec(src); + if (cap) { + const token = { + type: 'html', + block: true, + raw: cap[0], + pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style', + text: cap[0], + }; + return token; + } + } + def(src) { + const cap = this.rules.block.def.exec(src); + if (cap) { + const tag = cap[1].toLowerCase().replace(/\s+/g, ' '); + const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline.anyPunctuation, '$1') : ''; + const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3]; return { - text: c + type: 'def', + tag, + raw: cap[0], + href, + title, }; - }); } - - // parse child tokens inside headers and cells - - // header child tokens - l = item.header.length; - for (j = 0; j < l; j++) { - item.header[j].tokens = this.lexer.inline(item.header[j].text); + } + table(src) { + const cap = this.rules.block.table.exec(src); + if (!cap) { + return; } - - // cell child tokens - l = item.rows.length; - for (j = 0; j < l; j++) { - row = item.rows[j]; - for (k = 0; k < row.length; k++) { - row[k].tokens = this.lexer.inline(row[k].text); - } + if (!/[:|]/.test(cap[2])) { + // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading + return; + } + const headers = splitCells(cap[1]); + const aligns = cap[2].replace(/^\||\| *$/g, '').split('|'); + const rows = cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []; + const item = { + type: 'table', + raw: cap[0], + header: [], + align: [], + rows: [], + }; + if (headers.length !== aligns.length) { + // header and align columns must be equal, rows can be different. + return; + } + for (const align of aligns) { + if (/^ *-+: *$/.test(align)) { + item.align.push('right'); + } + else if (/^ *:-+: *$/.test(align)) { + item.align.push('center'); + } + else if (/^ *:-+ *$/.test(align)) { + item.align.push('left'); + } + else { + item.align.push(null); + } + } + for (let i = 0; i < headers.length; i++) { + item.header.push({ + text: headers[i], + tokens: this.lexer.inline(headers[i]), + header: true, + align: item.align[i], + }); + } + for (const row of rows) { + item.rows.push(splitCells(row, item.header.length).map((cell, i) => { + return { + text: cell, + tokens: this.lexer.inline(cell), + header: false, + align: item.align[i], + }; + })); } return item; - } - } - }; - _proto.lheading = function lheading(src) { - var cap = this.rules.block.lheading.exec(src); - if (cap) { - return { - type: 'heading', - raw: cap[0], - depth: cap[2].charAt(0) === '=' ? 1 : 2, - text: cap[1], - tokens: this.lexer.inline(cap[1]) - }; - } - }; - _proto.paragraph = function paragraph(src) { - var cap = this.rules.block.paragraph.exec(src); - if (cap) { - var text = cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1]; - return { - type: 'paragraph', - raw: cap[0], - text: text, - tokens: this.lexer.inline(text) - }; - } - }; - _proto.text = function text(src) { - var cap = this.rules.block.text.exec(src); - if (cap) { - return { - type: 'text', - raw: cap[0], - text: cap[0], - tokens: this.lexer.inline(cap[0]) - }; - } - }; - _proto.escape = function escape$1(src) { - var cap = this.rules.inline.escape.exec(src); - if (cap) { - return { - type: 'escape', - raw: cap[0], - text: escape(cap[1]) - }; - } - }; - _proto.tag = function tag(src) { - var cap = this.rules.inline.tag.exec(src); - if (cap) { - if (!this.lexer.state.inLink && /^/i.test(cap[0])) { - this.lexer.state.inLink = false; - } - if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { - this.lexer.state.inRawBlock = true; - } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { - this.lexer.state.inRawBlock = false; - } - return { - type: this.options.sanitize ? 'text' : 'html', - raw: cap[0], - inLink: this.lexer.state.inLink, - inRawBlock: this.lexer.state.inRawBlock, - block: false, - text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0] - }; - } - }; - _proto.link = function link(src) { - var cap = this.rules.inline.link.exec(src); - if (cap) { - var trimmedUrl = cap[2].trim(); - if (!this.options.pedantic && /^$/.test(trimmedUrl)) { - return; + } + lheading(src) { + const cap = this.rules.block.lheading.exec(src); + if (cap) { + return { + type: 'heading', + raw: cap[0], + depth: cap[2].charAt(0) === '=' ? 1 : 2, + text: cap[1], + tokens: this.lexer.inline(cap[1]), + }; } - - // ending angle bracket cannot be escaped - var rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\'); - if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { - return; - } - } else { - // find closing parenthesis - var lastParenIndex = findClosingBracket(cap[2], '()'); - if (lastParenIndex > -1) { - var start = cap[0].indexOf('!') === 0 ? 5 : 4; - var linkLen = start + cap[1].length + lastParenIndex; - cap[2] = cap[2].substring(0, lastParenIndex); - cap[0] = cap[0].substring(0, linkLen).trim(); - cap[3] = ''; - } - } - var href = cap[2]; - var title = ''; - if (this.options.pedantic) { - // split pedantic href and title - var link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); - if (link) { - href = link[1]; - title = link[3]; - } - } else { - title = cap[3] ? cap[3].slice(1, -1) : ''; - } - href = href.trim(); - if (/^$/.test(trimmedUrl)) { - // pedantic allows starting angle bracket without ending angle bracket - href = href.slice(1); - } else { - href = href.slice(1, -1); - } - } - return outputLink(cap, { - href: href ? href.replace(this.rules.inline._escapes, '$1') : href, - title: title ? title.replace(this.rules.inline._escapes, '$1') : title - }, cap[0], this.lexer); - } - }; - _proto.reflink = function reflink(src, links) { - var cap; - if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) { - var link = (cap[2] || cap[1]).replace(/\s+/g, ' '); - link = links[link.toLowerCase()]; - if (!link) { - var text = cap[0].charAt(0); - return { - type: 'text', - raw: text, - text: text - }; - } - return outputLink(cap, link, cap[0], this.lexer); } - }; - _proto.emStrong = function emStrong(src, maskedSrc, prevChar) { - if (prevChar === void 0) { - prevChar = ''; + paragraph(src) { + const cap = this.rules.block.paragraph.exec(src); + if (cap) { + const text = cap[1].charAt(cap[1].length - 1) === '\n' + ? cap[1].slice(0, -1) + : cap[1]; + return { + type: 'paragraph', + raw: cap[0], + text, + tokens: this.lexer.inline(text), + }; + } } - var match = this.rules.inline.emStrong.lDelim.exec(src); - if (!match) return; - - // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well - if (match[3] && prevChar.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE3F\uDE40\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDF02\uDF04-\uDF10\uDF12-\uDF33\uDF50-\uDF59\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883\uD885-\uD887][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F\uDC41-\uDC46]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD32\uDD50-\uDD52\uDD55\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEC0-\uDED3\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E\uDF25-\uDF2A]|\uD838[\uDC30-\uDC6D\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDCD0-\uDCEB\uDCF0-\uDCF9\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF39\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A\uDF50-\uDFFF]|\uD888[\uDC00-\uDFAF])/)) return; - var nextChar = match[1] || match[2] || ''; - if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) { - var lLength = match[0].length - 1; - var rDelim, - rLength, - delimTotal = lLength, - midDelimTotal = 0; - var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; - endReg.lastIndex = 0; - - // Clip maskedSrc to same section of string as src (move to lexer?) - maskedSrc = maskedSrc.slice(-1 * src.length + lLength); - while ((match = endReg.exec(maskedSrc)) != null) { - rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; - if (!rDelim) continue; // skip single * in __abc*abc__ - - rLength = rDelim.length; - if (match[3] || match[4]) { - // found another Left Delim - delimTotal += rLength; - continue; - } else if (match[5] || match[6]) { - // either Left or Right Delim - if (lLength % 3 && !((lLength + rLength) % 3)) { - midDelimTotal += rLength; - continue; // CommonMark Emphasis Rules 9-10 - } + text(src) { + const cap = this.rules.block.text.exec(src); + if (cap) { + return { + type: 'text', + raw: cap[0], + text: cap[0], + tokens: this.lexer.inline(cap[0]), + }; } - - delimTotal -= rLength; - if (delimTotal > 0) continue; // Haven't found enough closing delimiters - - // Remove extra characters. *a*** -> *a* - rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); - var raw = src.slice(0, lLength + match.index + (match[0].length - rDelim.length) + rLength); - - // Create `em` if smallest delimiter has odd char count. *a*** - if (Math.min(lLength, rLength) % 2) { - var _text = raw.slice(1, -1); - return { - type: 'em', - raw: raw, - text: _text, - tokens: this.lexer.inlineTokens(_text) - }; + } + escape(src) { + const cap = this.rules.inline.escape.exec(src); + if (cap) { + return { + type: 'escape', + raw: cap[0], + text: escape$1(cap[1]), + }; } - - // Create 'strong' if smallest delimiter has even char count. **a*** - var text = raw.slice(2, -2); - return { - type: 'strong', - raw: raw, - text: text, - tokens: this.lexer.inlineTokens(text) - }; - } - } - }; - _proto.codespan = function codespan(src) { - var cap = this.rules.inline.code.exec(src); - if (cap) { - var text = cap[2].replace(/\n/g, ' '); - var hasNonSpaceChars = /[^ ]/.test(text); - var hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text); - if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { - text = text.substring(1, text.length - 1); - } - text = escape(text, true); - return { - type: 'codespan', - raw: cap[0], - text: text - }; - } - }; - _proto.br = function br(src) { - var cap = this.rules.inline.br.exec(src); - if (cap) { - return { - type: 'br', - raw: cap[0] - }; - } - }; - _proto.del = function del(src) { - var cap = this.rules.inline.del.exec(src); - if (cap) { - return { - type: 'del', - raw: cap[0], - text: cap[2], - tokens: this.lexer.inlineTokens(cap[2]) - }; - } - }; - _proto.autolink = function autolink(src, mangle) { - var cap = this.rules.inline.autolink.exec(src); - if (cap) { - var text, href; - if (cap[2] === '@') { - text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]); - href = 'mailto:' + text; - } else { - text = escape(cap[1]); - href = text; - } - return { - type: 'link', - raw: cap[0], - text: text, - href: href, - tokens: [{ - type: 'text', - raw: text, - text: text - }] - }; - } - }; - _proto.url = function url(src, mangle) { - var cap; - if (cap = this.rules.inline.url.exec(src)) { - var text, href; - if (cap[2] === '@') { - text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]); - href = 'mailto:' + text; - } else { - // do extended autolink path validation - var prevCapZero; - do { - prevCapZero = cap[0]; - cap[0] = this.rules.inline._backpedal.exec(cap[0])[0]; - } while (prevCapZero !== cap[0]); - text = escape(cap[0]); - if (cap[1] === 'www.') { - href = 'http://' + cap[0]; - } else { - href = cap[0]; - } - } - return { - type: 'link', - raw: cap[0], - text: text, - href: href, - tokens: [{ - type: 'text', - raw: text, - text: text - }] - }; - } - }; - _proto.inlineText = function inlineText(src, smartypants) { - var cap = this.rules.inline.text.exec(src); - if (cap) { - var text; - if (this.lexer.state.inRawBlock) { - text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]; - } else { - text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]); - } - return { - type: 'text', - raw: cap[0], - text: text - }; - } - }; - return Tokenizer; - }(); + } + tag(src) { + const cap = this.rules.inline.tag.exec(src); + if (cap) { + if (!this.lexer.state.inLink && /^/i.test(cap[0])) { + this.lexer.state.inLink = false; + } + if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = true; + } + else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = false; + } + return { + type: 'html', + raw: cap[0], + inLink: this.lexer.state.inLink, + inRawBlock: this.lexer.state.inRawBlock, + block: false, + text: cap[0], + }; + } + } + link(src) { + const cap = this.rules.inline.link.exec(src); + if (cap) { + const trimmedUrl = cap[2].trim(); + if (!this.options.pedantic && /^$/.test(trimmedUrl))) { + return; + } + // ending angle bracket cannot be escaped + const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\'); + if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { + return; + } + } + else { + // find closing parenthesis + const lastParenIndex = findClosingBracket(cap[2], '()'); + if (lastParenIndex > -1) { + const start = cap[0].indexOf('!') === 0 ? 5 : 4; + const linkLen = start + cap[1].length + lastParenIndex; + cap[2] = cap[2].substring(0, lastParenIndex); + cap[0] = cap[0].substring(0, linkLen).trim(); + cap[3] = ''; + } + } + let href = cap[2]; + let title = ''; + if (this.options.pedantic) { + // split pedantic href and title + const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); + if (link) { + href = link[1]; + title = link[3]; + } + } + else { + title = cap[3] ? cap[3].slice(1, -1) : ''; + } + href = href.trim(); + if (/^$/.test(trimmedUrl))) { + // pedantic allows starting angle bracket without ending angle bracket + href = href.slice(1); + } + else { + href = href.slice(1, -1); + } + } + return outputLink(cap, { + href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href, + title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title, + }, cap[0], this.lexer); + } + } + reflink(src, links) { + let cap; + if ((cap = this.rules.inline.reflink.exec(src)) + || (cap = this.rules.inline.nolink.exec(src))) { + const linkString = (cap[2] || cap[1]).replace(/\s+/g, ' '); + const link = links[linkString.toLowerCase()]; + if (!link) { + const text = cap[0].charAt(0); + return { + type: 'text', + raw: text, + text, + }; + } + return outputLink(cap, link, cap[0], this.lexer); + } + } + emStrong(src, maskedSrc, prevChar = '') { + let match = this.rules.inline.emStrongLDelim.exec(src); + if (!match) + return; + // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well + if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) + return; + const nextChar = match[1] || match[2] || ''; + if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) { + // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below) + const lLength = [...match[0]].length - 1; + let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0; + const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd; + endReg.lastIndex = 0; + // Clip maskedSrc to same section of string as src (move to lexer?) + maskedSrc = maskedSrc.slice(-1 * src.length + lLength); + while ((match = endReg.exec(maskedSrc)) != null) { + rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; + if (!rDelim) + continue; // skip single * in __abc*abc__ + rLength = [...rDelim].length; + if (match[3] || match[4]) { // found another Left Delim + delimTotal += rLength; + continue; + } + else if (match[5] || match[6]) { // either Left or Right Delim + if (lLength % 3 && !((lLength + rLength) % 3)) { + midDelimTotal += rLength; + continue; // CommonMark Emphasis Rules 9-10 + } + } + delimTotal -= rLength; + if (delimTotal > 0) + continue; // Haven't found enough closing delimiters + // Remove extra characters. *a*** -> *a* + rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); + // char length can be >1 for unicode characters; + const lastCharLength = [...match[0]][0].length; + const raw = src.slice(0, lLength + match.index + lastCharLength + rLength); + // Create `em` if smallest delimiter has odd char count. *a*** + if (Math.min(lLength, rLength) % 2) { + const text = raw.slice(1, -1); + return { + type: 'em', + raw, + text, + tokens: this.lexer.inlineTokens(text), + }; + } + // Create 'strong' if smallest delimiter has even char count. **a*** + const text = raw.slice(2, -2); + return { + type: 'strong', + raw, + text, + tokens: this.lexer.inlineTokens(text), + }; + } + } + } + codespan(src) { + const cap = this.rules.inline.code.exec(src); + if (cap) { + let text = cap[2].replace(/\n/g, ' '); + const hasNonSpaceChars = /[^ ]/.test(text); + const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text); + if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { + text = text.substring(1, text.length - 1); + } + text = escape$1(text, true); + return { + type: 'codespan', + raw: cap[0], + text, + }; + } + } + br(src) { + const cap = this.rules.inline.br.exec(src); + if (cap) { + return { + type: 'br', + raw: cap[0], + }; + } + } + del(src) { + const cap = this.rules.inline.del.exec(src); + if (cap) { + return { + type: 'del', + raw: cap[0], + text: cap[2], + tokens: this.lexer.inlineTokens(cap[2]), + }; + } + } + autolink(src) { + const cap = this.rules.inline.autolink.exec(src); + if (cap) { + let text, href; + if (cap[2] === '@') { + text = escape$1(cap[1]); + href = 'mailto:' + text; + } + else { + text = escape$1(cap[1]); + href = text; + } + return { + type: 'link', + raw: cap[0], + text, + href, + tokens: [ + { + type: 'text', + raw: text, + text, + }, + ], + }; + } + } + url(src) { + let cap; + if (cap = this.rules.inline.url.exec(src)) { + let text, href; + if (cap[2] === '@') { + text = escape$1(cap[0]); + href = 'mailto:' + text; + } + else { + // do extended autolink path validation + let prevCapZero; + do { + prevCapZero = cap[0]; + cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? ''; + } while (prevCapZero !== cap[0]); + text = escape$1(cap[0]); + if (cap[1] === 'www.') { + href = 'http://' + cap[0]; + } + else { + href = cap[0]; + } + } + return { + type: 'link', + raw: cap[0], + text, + href, + tokens: [ + { + type: 'text', + raw: text, + text, + }, + ], + }; + } + } + inlineText(src) { + const cap = this.rules.inline.text.exec(src); + if (cap) { + let text; + if (this.lexer.state.inRawBlock) { + text = cap[0]; + } + else { + text = escape$1(cap[0]); + } + return { + type: 'text', + raw: cap[0], + text, + }; + } + } + } /** * Block-Level Grammar */ - var block = { - newline: /^(?: *(?:\n|$))+/, - code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, - fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/, - hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, - heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, - blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, - list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, - html: '^ {0,3}(?:' // optional indentation - + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)' // (1) - + '|comment[^\\n]*(\\n+|$)' // (2) - + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3) - + '|\\n*|$)' // (4) - + '|\\n*|$)' // (5) - + '|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6) - + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag - + '|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag - + ')', - def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, - table: noopTest, - lheading: /^((?:.|\n(?!\n))+?)\n {0,3}(=+|-+) *(?:\n+|$)/, - // regex template, placeholders will be replaced according to different paragraph - // interruption rules of commonmark and the original markdown spec: - _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, - text: /^[^\n]+/ - }; - block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/; - block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; - block.def = edit(block.def).replace('label', block._label).replace('title', block._title).getRegex(); - block.bullet = /(?:[*+-]|\d{1,9}[.)])/; - block.listItemStart = edit(/^( *)(bull) */).replace('bull', block.bullet).getRegex(); - block.list = edit(block.list).replace(/bull/g, block.bullet).replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))').replace('def', '\\n+(?=' + block.def.source + ')').getRegex(); - block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul'; - block._comment = /|$)/; - block.html = edit(block.html, 'i').replace('comment', block._comment).replace('tag', block._tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); - block.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs - .replace('|table', '').replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt - .replace('html', ')|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks - .getRegex(); - block.blockquote = edit(block.blockquote).replace('paragraph', block.paragraph).getRegex(); - + const newline = /^(?: *(?:\n|$))+/; + const blockCode = /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/; + const fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/; + const hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/; + const heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/; + const bullet = /(?:[*+-]|\d{1,9}[.)])/; + const lheading = edit(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/) + .replace(/bull/g, bullet) // lists can interrupt + .replace(/blockCode/g, / {4}/) // indented code blocks can interrupt + .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt + .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt + .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt + .replace(/html/g, / {0,3}<[^\n>]+>\n/) // block html can interrupt + .getRegex(); + const _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/; + const blockText = /^[^\n]+/; + const _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/; + const def = edit(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/) + .replace('label', _blockLabel) + .replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/) + .getRegex(); + const list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/) + .replace(/bull/g, bullet) + .getRegex(); + const _tag = 'address|article|aside|base|basefont|blockquote|body|caption' + + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title' + + '|tr|track|ul'; + const _comment = /|$))/; + const html = edit('^ {0,3}(?:' // optional indentation + + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)' // (1) + + '|comment[^\\n]*(\\n+|$)' // (2) + + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3) + + '|\\n*|$)' // (4) + + '|\\n*|$)' // (5) + + '|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6) + + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag + + '|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag + + ')', 'i') + .replace('comment', _comment) + .replace('tag', _tag) + .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/) + .getRegex(); + const paragraph = edit(_paragraph) + .replace('hr', hr) + .replace('heading', ' {0,3}#{1,6}(?:\\s|$)') + .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs + .replace('|table', '') + .replace('blockquote', ' {0,3}>') + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)') + .replace('tag', _tag) // pars can be interrupted by type (6) html blocks + .getRegex(); + const blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/) + .replace('paragraph', paragraph) + .getRegex(); /** * Normal Block Grammar */ - - block.normal = _extends({}, block); - + const blockNormal = { + blockquote, + code: blockCode, + def, + fences, + heading, + hr, + html, + lheading, + list, + newline, + paragraph, + table: noopTest, + text: blockText, + }; /** * GFM Block Grammar */ - - block.gfm = _extends({}, block.normal, { - table: '^ *([^\\n ].*\\|.*)\\n' // Header - + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align - + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells - }); - - block.gfm.table = edit(block.gfm.table).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('blockquote', ' {0,3}>').replace('code', ' {4}[^\\n]').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt - .replace('html', ')|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // tables can be interrupted by type (6) html blocks - .getRegex(); - block.gfm.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs - .replace('table', block.gfm.table) // interrupt paragraphs with table - .replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt - .replace('html', ')|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks - .getRegex(); + const gfmTable = edit('^ *([^\\n ].*)\\n' // Header + + ' {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)' // Align + + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)') // Cells + .replace('hr', hr) + .replace('heading', ' {0,3}#{1,6}(?:\\s|$)') + .replace('blockquote', ' {0,3}>') + .replace('code', ' {4}[^\\n]') + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)') + .replace('tag', _tag) // tables can be interrupted by type (6) html blocks + .getRegex(); + const blockGfm = { + ...blockNormal, + table: gfmTable, + paragraph: edit(_paragraph) + .replace('hr', hr) + .replace('heading', ' {0,3}#{1,6}(?:\\s|$)') + .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs + .replace('table', gfmTable) // interrupt paragraphs with table + .replace('blockquote', ' {0,3}>') + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt + .replace('html', ')|<(?:script|pre|style|textarea|!--)') + .replace('tag', _tag) // pars can be interrupted by type (6) html blocks + .getRegex(), + }; /** * Pedantic grammar (original John Gruber's loose markdown specification) */ - - block.pedantic = _extends({}, block.normal, { - html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)' // closed tag - + '|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))').replace('comment', block._comment).replace(/tag/g, '(?!(?:' + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b').getRegex(), - def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, - heading: /^(#{1,6})(.*)(?:\n+|$)/, - fences: noopTest, - // fences not supported - lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, - paragraph: edit(block.normal._paragraph).replace('hr', block.hr).replace('heading', ' *#{1,6} *[^\n]').replace('lheading', block.lheading).replace('blockquote', ' {0,3}>').replace('|fences', '').replace('|list', '').replace('|html', '').getRegex() - }); - + const blockPedantic = { + ...blockNormal, + html: edit('^ *(?:comment *(?:\\n|\\s*$)' + + '|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)' // closed tag + + '|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))') + .replace('comment', _comment) + .replace(/tag/g, '(?!(?:' + + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b') + .getRegex(), + def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, + heading: /^(#{1,6})(.*)(?:\n+|$)/, + fences: noopTest, // fences not supported + lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, + paragraph: edit(_paragraph) + .replace('hr', hr) + .replace('heading', ' *#{1,6} *[^\n]') + .replace('lheading', lheading) + .replace('|table', '') + .replace('blockquote', ' {0,3}>') + .replace('|fences', '') + .replace('|list', '') + .replace('|html', '') + .replace('|tag', '') + .getRegex(), + }; /** * Inline-Level Grammar */ - var inline = { - escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, - autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, - url: noopTest, - tag: '^comment' + '|^' // self-closing tag - + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag - + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. - + '|^' // declaration, e.g. - + '|^', - // CDATA section - link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, - reflink: /^!?\[(label)\]\[(ref)\]/, - nolink: /^!?\[(ref)\](?:\[\])?/, - reflinkSearch: 'reflink|nolink(?!\\()', - emStrong: { - lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, - // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. - // () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a - rDelimAst: /^(?:[^_*\\]|\\.)*?\_\_(?:[^_*\\]|\\.)*?\*(?:[^_*\\]|\\.)*?(?=\_\_)|(?:[^*\\]|\\.)+(?=[^*])|[punct_](\*+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|(?:[^punct*_\s\\]|\\.)(\*+)(?=[^punct*_\s])/, - rDelimUnd: /^(?:[^_*\\]|\\.)*?\*\*(?:[^_*\\]|\\.)*?\_(?:[^_*\\]|\\.)*?(?=\*\*)|(?:[^_\\]|\\.)+(?=[^_])|[punct*](\_+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _ - }, - - code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, - br: /^( {2,}|\\)\n(?!\s*$)/, - del: noopTest, - text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~'; - inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex(); - + const escape = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/; + const inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/; + const br = /^( {2,}|\\)\n(?!\s*$)/; + const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\ - inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g; - // lookbehind is not available on Safari as of version 16 - // inline.escapedEmSt = /(?<=(?:^|[^\\)(?:\\[^])*)\\[*_]/g; - inline.escapedEmSt = /(?:^|[^\\])(?:\\\\)*\\[*_]/g; - inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex(); - inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex(); - inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g').replace(/punct/g, inline._punctuation).getRegex(); - inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g').replace(/punct/g, inline._punctuation).getRegex(); - inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g; - inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/; - inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/; - inline.autolink = edit(inline.autolink).replace('scheme', inline._scheme).replace('email', inline._email).getRegex(); - inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/; - inline.tag = edit(inline.tag).replace('comment', inline._comment).replace('attribute', inline._attribute).getRegex(); - inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; - inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/; - inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; - inline.link = edit(inline.link).replace('label', inline._label).replace('href', inline._href).replace('title', inline._title).getRegex(); - inline.reflink = edit(inline.reflink).replace('label', inline._label).replace('ref', block._label).getRegex(); - inline.nolink = edit(inline.nolink).replace('ref', block._label).getRegex(); - inline.reflinkSearch = edit(inline.reflinkSearch, 'g').replace('reflink', inline.reflink).replace('nolink', inline.nolink).getRegex(); - + const blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g; + const emStrongLDelim = edit(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, 'u') + .replace(/punct/g, _punctuation) + .getRegex(); + const emStrongRDelimAst = edit('^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong + + '|[^*]+(?=[^*])' // Consume to delim + + '|(?!\\*)[punct](\\*+)(?=[\\s]|$)' // (1) #*** can only be a Right Delimiter + + '|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)' // (2) a***#, a*** can only be a Right Delimiter + + '|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])' // (3) #***a, ***a can only be Left Delimiter + + '|[\\s](\\*+)(?!\\*)(?=[punct])' // (4) ***# can only be Left Delimiter + + '|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])' // (5) #***# can be either Left or Right Delimiter + + '|[^punct\\s](\\*+)(?=[^punct\\s])', 'gu') // (6) a***a can be either Left or Right Delimiter + .replace(/punct/g, _punctuation) + .getRegex(); + // (6) Not allowed for _ + const emStrongRDelimUnd = edit('^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)' // Skip orphan inside strong + + '|[^_]+(?=[^_])' // Consume to delim + + '|(?!_)[punct](_+)(?=[\\s]|$)' // (1) #___ can only be a Right Delimiter + + '|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)' // (2) a___#, a___ can only be a Right Delimiter + + '|(?!_)[punct\\s](_+)(?=[^punct\\s])' // (3) #___a, ___a can only be Left Delimiter + + '|[\\s](_+)(?!_)(?=[punct])' // (4) ___# can only be Left Delimiter + + '|(?!_)[punct](_+)(?!_)(?=[punct])', 'gu') // (5) #___# can be either Left or Right Delimiter + .replace(/punct/g, _punctuation) + .getRegex(); + const anyPunctuation = edit(/\\([punct])/, 'gu') + .replace(/punct/g, _punctuation) + .getRegex(); + const autolink = edit(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/) + .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/) + .replace('email', /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/) + .getRegex(); + const _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex(); + const tag = edit('^comment' + + '|^' // self-closing tag + + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag + + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. + + '|^' // declaration, e.g. + + '|^') // CDATA section + .replace('comment', _inlineComment) + .replace('attribute', /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/) + .getRegex(); + const _inlineLabel = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; + const link = edit(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/) + .replace('label', _inlineLabel) + .replace('href', /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/) + .replace('title', /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/) + .getRegex(); + const reflink = edit(/^!?\[(label)\]\[(ref)\]/) + .replace('label', _inlineLabel) + .replace('ref', _blockLabel) + .getRegex(); + const nolink = edit(/^!?\[(ref)\](?:\[\])?/) + .replace('ref', _blockLabel) + .getRegex(); + const reflinkSearch = edit('reflink|nolink(?!\\()', 'g') + .replace('reflink', reflink) + .replace('nolink', nolink) + .getRegex(); /** * Normal Inline Grammar */ - - inline.normal = _extends({}, inline); - + const inlineNormal = { + _backpedal: noopTest, // only used for GFM url + anyPunctuation, + autolink, + blockSkip, + br, + code: inlineCode, + del: noopTest, + emStrongLDelim, + emStrongRDelimAst, + emStrongRDelimUnd, + escape, + link, + nolink, + punctuation, + reflink, + reflinkSearch, + tag, + text: inlineText, + url: noopTest, + }; /** * Pedantic Inline Grammar */ - - inline.pedantic = _extends({}, inline.normal, { - strong: { - start: /^__|\*\*/, - middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, - endAst: /\*\*(?!\*)/g, - endUnd: /__(?!_)/g - }, - em: { - start: /^_|\*/, - middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, - endAst: /\*(?!\*)/g, - endUnd: /_(?!_)/g - }, - link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', inline._label).getRegex(), - reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', inline._label).getRegex() - }); - + const inlinePedantic = { + ...inlineNormal, + link: edit(/^!?\[(label)\]\((.*?)\)/) + .replace('label', _inlineLabel) + .getRegex(), + reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/) + .replace('label', _inlineLabel) + .getRegex(), + }; /** * GFM Inline Grammar */ - - inline.gfm = _extends({}, inline.normal, { - escape: edit(inline.escape).replace('])', '~|])').getRegex(), - _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, - url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, - _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, - del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, - text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ 0.5) { - ch = 'x' + ch.toString(16); - } - out += '&#' + ch + ';'; - } - return out; - } + const block = { + normal: blockNormal, + gfm: blockGfm, + pedantic: blockPedantic, + }; + const inline = { + normal: inlineNormal, + gfm: inlineGfm, + breaks: inlineBreaks, + pedantic: inlinePedantic, + }; /** * Block Lexer */ - var Lexer = /*#__PURE__*/function () { - function Lexer(options) { - this.tokens = []; - this.tokens.links = Object.create(null); - this.options = options || exports.defaults; - this.options.tokenizer = this.options.tokenizer || new Tokenizer(); - this.tokenizer = this.options.tokenizer; - this.tokenizer.options = this.options; - this.tokenizer.lexer = this; - this.inlineQueue = []; - this.state = { - inLink: false, - inRawBlock: false, - top: true - }; - var rules = { - block: block.normal, - inline: inline.normal - }; - if (this.options.pedantic) { - rules.block = block.pedantic; - rules.inline = inline.pedantic; - } else if (this.options.gfm) { - rules.block = block.gfm; - if (this.options.breaks) { - rules.inline = inline.breaks; - } else { - rules.inline = inline.gfm; - } - } - this.tokenizer.rules = rules; - } - - /** - * Expose Rules - */ - /** - * Static Lex Method - */ - Lexer.lex = function lex(src, options) { - var lexer = new Lexer(options); - return lexer.lex(src); - } - - /** - * Static Lex Inline Method - */; - Lexer.lexInline = function lexInline(src, options) { - var lexer = new Lexer(options); - return lexer.inlineTokens(src); - } - - /** - * Preprocessing - */; - var _proto = Lexer.prototype; - _proto.lex = function lex(src) { - src = src.replace(/\r\n|\r/g, '\n'); - this.blockTokens(src, this.tokens); - var next; - while (next = this.inlineQueue.shift()) { - this.inlineTokens(next.src, next.tokens); - } - return this.tokens; - } - - /** - * Lexing - */; - _proto.blockTokens = function blockTokens(src, tokens) { - var _this = this; - if (tokens === void 0) { - tokens = []; - } - if (this.options.pedantic) { - src = src.replace(/\t/g, ' ').replace(/^ +$/gm, ''); - } else { - src = src.replace(/^( *)(\t+)/gm, function (_, leading, tabs) { - return leading + ' '.repeat(tabs.length); - }); - } - var token, lastToken, cutSrc, lastParagraphClipped; - var _loop = function _loop() { - if (_this.options.extensions && _this.options.extensions.block && _this.options.extensions.block.some(function (extTokenizer) { - if (token = extTokenizer.call({ - lexer: _this - }, src, tokens)) { - src = src.substring(token.raw.length); - tokens.push(token); - return true; - } - return false; - })) { - return "continue"; - } - - // newline - if (token = _this.tokenizer.space(src)) { - src = src.substring(token.raw.length); - if (token.raw.length === 1 && tokens.length > 0) { - // if there's a single \n as a spacer, it's terminating the last line, - // so move it there so that we don't get unecessary paragraph tags - tokens[tokens.length - 1].raw += '\n'; - } else { - tokens.push(token); - } - return "continue"; - } - - // code - if (token = _this.tokenizer.code(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - // An indented code block cannot interrupt a paragraph. - if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { - lastToken.raw += '\n' + token.raw; - lastToken.text += '\n' + token.text; - _this.inlineQueue[_this.inlineQueue.length - 1].src = lastToken.text; - } else { - tokens.push(token); - } - return "continue"; - } - - // fences - if (token = _this.tokenizer.fences(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // heading - if (token = _this.tokenizer.heading(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // hr - if (token = _this.tokenizer.hr(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // blockquote - if (token = _this.tokenizer.blockquote(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // list - if (token = _this.tokenizer.list(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // html - if (token = _this.tokenizer.html(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // def - if (token = _this.tokenizer.def(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { - lastToken.raw += '\n' + token.raw; - lastToken.text += '\n' + token.raw; - _this.inlineQueue[_this.inlineQueue.length - 1].src = lastToken.text; - } else if (!_this.tokens.links[token.tag]) { - _this.tokens.links[token.tag] = { - href: token.href, - title: token.title - }; - } - return "continue"; - } - - // table (gfm) - if (token = _this.tokenizer.table(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // lheading - if (token = _this.tokenizer.lheading(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // top-level paragraph - // prevent paragraph consuming extensions by clipping 'src' to extension start - cutSrc = src; - if (_this.options.extensions && _this.options.extensions.startBlock) { - var startIndex = Infinity; - var tempSrc = src.slice(1); - var tempStart; - _this.options.extensions.startBlock.forEach(function (getStartIndex) { - tempStart = getStartIndex.call({ - lexer: this - }, tempSrc); - if (typeof tempStart === 'number' && tempStart >= 0) { - startIndex = Math.min(startIndex, tempStart); - } - }); - if (startIndex < Infinity && startIndex >= 0) { - cutSrc = src.substring(0, startIndex + 1); - } - } - if (_this.state.top && (token = _this.tokenizer.paragraph(cutSrc))) { - lastToken = tokens[tokens.length - 1]; - if (lastParagraphClipped && lastToken.type === 'paragraph') { - lastToken.raw += '\n' + token.raw; - lastToken.text += '\n' + token.text; - _this.inlineQueue.pop(); - _this.inlineQueue[_this.inlineQueue.length - 1].src = lastToken.text; - } else { - tokens.push(token); - } - lastParagraphClipped = cutSrc.length !== src.length; - src = src.substring(token.raw.length); - return "continue"; - } - - // text - if (token = _this.tokenizer.text(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && lastToken.type === 'text') { - lastToken.raw += '\n' + token.raw; - lastToken.text += '\n' + token.text; - _this.inlineQueue.pop(); - _this.inlineQueue[_this.inlineQueue.length - 1].src = lastToken.text; - } else { - tokens.push(token); - } - return "continue"; - } - if (src) { - var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); - if (_this.options.silent) { - console.error(errMsg); - return "break"; - } else { - throw new Error(errMsg); - } - } - }; - while (src) { - var _ret = _loop(); - if (_ret === "continue") continue; - if (_ret === "break") break; - } - this.state.top = true; - return tokens; - }; - _proto.inline = function inline(src, tokens) { - if (tokens === void 0) { - tokens = []; - } - this.inlineQueue.push({ - src: src, - tokens: tokens - }); - return tokens; - } - - /** - * Lexing/Compiling - */; - _proto.inlineTokens = function inlineTokens(src, tokens) { - var _this2 = this; - if (tokens === void 0) { - tokens = []; - } - var token, lastToken, cutSrc; - - // String with links masked to avoid interference with em and strong - var maskedSrc = src; - var match; - var keepPrevChar, prevChar; - - // Mask out reflinks - if (this.tokens.links) { - var links = Object.keys(this.tokens.links); - if (links.length > 0) { - while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { - if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) { - maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); - } + class _Lexer { + tokens; + options; + state; + tokenizer; + inlineQueue; + constructor(options) { + // TokenList cannot be created in one go + this.tokens = []; + this.tokens.links = Object.create(null); + this.options = options || exports.defaults; + this.options.tokenizer = this.options.tokenizer || new _Tokenizer(); + this.tokenizer = this.options.tokenizer; + this.tokenizer.options = this.options; + this.tokenizer.lexer = this; + this.inlineQueue = []; + this.state = { + inLink: false, + inRawBlock: false, + top: true, + }; + const rules = { + block: block.normal, + inline: inline.normal, + }; + if (this.options.pedantic) { + rules.block = block.pedantic; + rules.inline = inline.pedantic; + } + else if (this.options.gfm) { + rules.block = block.gfm; + if (this.options.breaks) { + rules.inline = inline.breaks; + } + else { + rules.inline = inline.gfm; + } } - } + this.tokenizer.rules = rules; } - // Mask out other blocks - while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { - maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + /** + * Expose Rules + */ + static get rules() { + return { + block, + inline, + }; } - - // Mask out escaped em & strong delimiters - while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) { - maskedSrc = maskedSrc.slice(0, match.index + match[0].length - 2) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex); - this.tokenizer.rules.inline.escapedEmSt.lastIndex--; - } - var _loop2 = function _loop2() { - if (!keepPrevChar) { - prevChar = ''; - } - keepPrevChar = false; - - // extensions - if (_this2.options.extensions && _this2.options.extensions.inline && _this2.options.extensions.inline.some(function (extTokenizer) { - if (token = extTokenizer.call({ - lexer: _this2 - }, src, tokens)) { - src = src.substring(token.raw.length); - tokens.push(token); - return true; - } - return false; - })) { - return "continue"; - } - - // escape - if (token = _this2.tokenizer.escape(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // tag - if (token = _this2.tokenizer.tag(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && token.type === 'text' && lastToken.type === 'text') { - lastToken.raw += token.raw; - lastToken.text += token.text; - } else { - tokens.push(token); - } - return "continue"; - } - - // link - if (token = _this2.tokenizer.link(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // reflink, nolink - if (token = _this2.tokenizer.reflink(src, _this2.tokens.links)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && token.type === 'text' && lastToken.type === 'text') { - lastToken.raw += token.raw; - lastToken.text += token.text; - } else { - tokens.push(token); - } - return "continue"; - } - - // em & strong - if (token = _this2.tokenizer.emStrong(src, maskedSrc, prevChar)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // code - if (token = _this2.tokenizer.codespan(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // br - if (token = _this2.tokenizer.br(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // del (gfm) - if (token = _this2.tokenizer.del(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // autolink - if (token = _this2.tokenizer.autolink(src, mangle)) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // url (gfm) - if (!_this2.state.inLink && (token = _this2.tokenizer.url(src, mangle))) { - src = src.substring(token.raw.length); - tokens.push(token); - return "continue"; - } - - // text - // prevent inlineText consuming extensions by clipping 'src' to extension start - cutSrc = src; - if (_this2.options.extensions && _this2.options.extensions.startInline) { - var startIndex = Infinity; - var tempSrc = src.slice(1); - var tempStart; - _this2.options.extensions.startInline.forEach(function (getStartIndex) { - tempStart = getStartIndex.call({ - lexer: this - }, tempSrc); - if (typeof tempStart === 'number' && tempStart >= 0) { - startIndex = Math.min(startIndex, tempStart); - } - }); - if (startIndex < Infinity && startIndex >= 0) { - cutSrc = src.substring(0, startIndex + 1); - } - } - if (token = _this2.tokenizer.inlineText(cutSrc, smartypants)) { - src = src.substring(token.raw.length); - if (token.raw.slice(-1) !== '_') { - // Track prevChar before string of ____ started - prevChar = token.raw.slice(-1); - } - keepPrevChar = true; - lastToken = tokens[tokens.length - 1]; - if (lastToken && lastToken.type === 'text') { - lastToken.raw += token.raw; - lastToken.text += token.text; - } else { - tokens.push(token); - } - return "continue"; - } - if (src) { - var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); - if (_this2.options.silent) { - console.error(errMsg); - return "break"; - } else { - throw new Error(errMsg); - } - } - }; - while (src) { - var _ret2 = _loop2(); - if (_ret2 === "continue") continue; - if (_ret2 === "break") break; - } - return tokens; - }; - _createClass(Lexer, null, [{ - key: "rules", - get: function get() { - return { - block: block, - inline: inline - }; - } - }]); - return Lexer; - }(); + /** + * Static Lex Method + */ + static lex(src, options) { + const lexer = new _Lexer(options); + return lexer.lex(src); + } + /** + * Static Lex Inline Method + */ + static lexInline(src, options) { + const lexer = new _Lexer(options); + return lexer.inlineTokens(src); + } + /** + * Preprocessing + */ + lex(src) { + src = src + .replace(/\r\n|\r/g, '\n'); + this.blockTokens(src, this.tokens); + for (let i = 0; i < this.inlineQueue.length; i++) { + const next = this.inlineQueue[i]; + this.inlineTokens(next.src, next.tokens); + } + this.inlineQueue = []; + return this.tokens; + } + blockTokens(src, tokens = [], lastParagraphClipped = false) { + if (this.options.pedantic) { + src = src.replace(/\t/g, ' ').replace(/^ +$/gm, ''); + } + else { + src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => { + return leading + ' '.repeat(tabs.length); + }); + } + let token; + let lastToken; + let cutSrc; + while (src) { + if (this.options.extensions + && this.options.extensions.block + && this.options.extensions.block.some((extTokenizer) => { + if (token = extTokenizer.call({ lexer: this }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + return false; + })) { + continue; + } + // newline + if (token = this.tokenizer.space(src)) { + src = src.substring(token.raw.length); + if (token.raw.length === 1 && tokens.length > 0) { + // if there's a single \n as a spacer, it's terminating the last line, + // so move it there so that we don't get unnecessary paragraph tags + tokens[tokens.length - 1].raw += '\n'; + } + else { + tokens.push(token); + } + continue; + } + // code + if (token = this.tokenizer.code(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + // An indented code block cannot interrupt a paragraph. + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } + else { + tokens.push(token); + } + continue; + } + // fences + if (token = this.tokenizer.fences(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // heading + if (token = this.tokenizer.heading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // hr + if (token = this.tokenizer.hr(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // blockquote + if (token = this.tokenizer.blockquote(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // list + if (token = this.tokenizer.list(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // html + if (token = this.tokenizer.html(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // def + if (token = this.tokenizer.def(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.raw; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } + else if (!this.tokens.links[token.tag]) { + this.tokens.links[token.tag] = { + href: token.href, + title: token.title, + }; + } + continue; + } + // table (gfm) + if (token = this.tokenizer.table(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // lheading + if (token = this.tokenizer.lheading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // top-level paragraph + // prevent paragraph consuming extensions by clipping 'src' to extension start + cutSrc = src; + if (this.options.extensions && this.options.extensions.startBlock) { + let startIndex = Infinity; + const tempSrc = src.slice(1); + let tempStart; + this.options.extensions.startBlock.forEach((getStartIndex) => { + tempStart = getStartIndex.call({ lexer: this }, tempSrc); + if (typeof tempStart === 'number' && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); + } + }); + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + } + if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { + lastToken = tokens[tokens.length - 1]; + if (lastParagraphClipped && lastToken?.type === 'paragraph') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } + else { + tokens.push(token); + } + lastParagraphClipped = (cutSrc.length !== src.length); + src = src.substring(token.raw.length); + continue; + } + // text + if (token = this.tokenizer.text(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && lastToken.type === 'text') { + lastToken.raw += '\n' + token.raw; + lastToken.text += '\n' + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } + else { + tokens.push(token); + } + continue; + } + if (src) { + const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + if (this.options.silent) { + console.error(errMsg); + break; + } + else { + throw new Error(errMsg); + } + } + } + this.state.top = true; + return tokens; + } + inline(src, tokens = []) { + this.inlineQueue.push({ src, tokens }); + return tokens; + } + /** + * Lexing/Compiling + */ + inlineTokens(src, tokens = []) { + let token, lastToken, cutSrc; + // String with links masked to avoid interference with em and strong + let maskedSrc = src; + let match; + let keepPrevChar, prevChar; + // Mask out reflinks + if (this.tokens.links) { + const links = Object.keys(this.tokens.links); + if (links.length > 0) { + while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { + if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); + } + } + } + } + // Mask out other blocks + while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + } + // Mask out escaped characters + while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex); + } + while (src) { + if (!keepPrevChar) { + prevChar = ''; + } + keepPrevChar = false; + // extensions + if (this.options.extensions + && this.options.extensions.inline + && this.options.extensions.inline.some((extTokenizer) => { + if (token = extTokenizer.call({ lexer: this }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + return false; + })) { + continue; + } + // escape + if (token = this.tokenizer.escape(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // tag + if (token = this.tokenizer.tag(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } + else { + tokens.push(token); + } + continue; + } + // link + if (token = this.tokenizer.link(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // reflink, nolink + if (token = this.tokenizer.reflink(src, this.tokens.links)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && token.type === 'text' && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } + else { + tokens.push(token); + } + continue; + } + // em & strong + if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // code + if (token = this.tokenizer.codespan(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // br + if (token = this.tokenizer.br(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // del (gfm) + if (token = this.tokenizer.del(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // autolink + if (token = this.tokenizer.autolink(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // url (gfm) + if (!this.state.inLink && (token = this.tokenizer.url(src))) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + // text + // prevent inlineText consuming extensions by clipping 'src' to extension start + cutSrc = src; + if (this.options.extensions && this.options.extensions.startInline) { + let startIndex = Infinity; + const tempSrc = src.slice(1); + let tempStart; + this.options.extensions.startInline.forEach((getStartIndex) => { + tempStart = getStartIndex.call({ lexer: this }, tempSrc); + if (typeof tempStart === 'number' && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); + } + }); + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + } + if (token = this.tokenizer.inlineText(cutSrc)) { + src = src.substring(token.raw.length); + if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started + prevChar = token.raw.slice(-1); + } + keepPrevChar = true; + lastToken = tokens[tokens.length - 1]; + if (lastToken && lastToken.type === 'text') { + lastToken.raw += token.raw; + lastToken.text += token.text; + } + else { + tokens.push(token); + } + continue; + } + if (src) { + const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + if (this.options.silent) { + console.error(errMsg); + break; + } + else { + throw new Error(errMsg); + } + } + } + return tokens; + } + } /** * Renderer */ - var Renderer = /*#__PURE__*/function () { - function Renderer(options) { - this.options = options || exports.defaults; - } - var _proto = Renderer.prototype; - _proto.code = function code(_code, infostring, escaped) { - var lang = (infostring || '').match(/\S*/)[0]; - if (this.options.highlight) { - var out = this.options.highlight(_code, lang); - if (out != null && out !== _code) { - escaped = true; - _code = out; - } - } - _code = _code.replace(/\n$/, '') + '\n'; - if (!lang) { - return '
    ' + (escaped ? _code : escape(_code, true)) + '
    \n'; - } - return '
    ' + (escaped ? _code : escape(_code, true)) + '
    \n'; - } - - /** - * @param {string} quote - */; - _proto.blockquote = function blockquote(quote) { - return "
    \n" + quote + "
    \n"; - }; - _proto.html = function html(_html, block) { - return _html; - } - - /** - * @param {string} text - * @param {string} level - * @param {string} raw - * @param {any} slugger - */; - _proto.heading = function heading(text, level, raw, slugger) { - if (this.options.headerIds) { - var id = this.options.headerPrefix + slugger.slug(raw); - return "" + text + "\n"; + class _Renderer { + options; + parser; // set by the parser + constructor(options) { + this.options = options || exports.defaults; + } + space(token) { + return ''; + } + code({ text, lang, escaped }) { + const langString = (lang || '').match(/^\S*/)?.[0]; + const code = text.replace(/\n$/, '') + '\n'; + if (!langString) { + return '
    '
    +                  + (escaped ? code : escape$1(code, true))
    +                  + '
    \n'; + } + return '
    '
    +              + (escaped ? code : escape$1(code, true))
    +              + '
    \n'; + } + blockquote({ tokens }) { + const body = this.parser.parse(tokens); + return `
    \n${body}
    \n`; + } + html({ text }) { + return text; + } + heading({ tokens, depth }) { + return `${this.parser.parseInline(tokens)}\n`; + } + hr(token) { + return '
    \n'; + } + list(token) { + const ordered = token.ordered; + const start = token.start; + let body = ''; + for (let j = 0; j < token.items.length; j++) { + const item = token.items[j]; + body += this.listitem(item); + } + const type = ordered ? 'ol' : 'ul'; + const startAttr = (ordered && start !== 1) ? (' start="' + start + '"') : ''; + return '<' + type + startAttr + '>\n' + body + '\n'; + } + listitem(item) { + let itemBody = ''; + if (item.task) { + const checkbox = this.checkbox({ checked: !!item.checked }); + if (item.loose) { + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + } + } + else { + item.tokens.unshift({ + type: 'text', + raw: checkbox + ' ', + text: checkbox + ' ', + }); + } + } + else { + itemBody += checkbox + ' '; + } + } + itemBody += this.parser.parse(item.tokens, !!item.loose); + return `
  • ${itemBody}
  • \n`; + } + checkbox({ checked }) { + return ''; + } + paragraph({ tokens }) { + return `

    ${this.parser.parseInline(tokens)}

    \n`; + } + table(token) { + let header = ''; + // header + let cell = ''; + for (let j = 0; j < token.header.length; j++) { + cell += this.tablecell(token.header[j]); + } + header += this.tablerow({ text: cell }); + let body = ''; + for (let j = 0; j < token.rows.length; j++) { + const row = token.rows[j]; + cell = ''; + for (let k = 0; k < row.length; k++) { + cell += this.tablecell(row[k]); + } + body += this.tablerow({ text: cell }); + } + if (body) + body = `${body}`; + return '\n' + + '\n' + + header + + '\n' + + body + + '
    \n'; + } + tablerow({ text }) { + return `\n${text}\n`; + } + tablecell(token) { + const content = this.parser.parseInline(token.tokens); + const type = token.header ? 'th' : 'td'; + const tag = token.align + ? `<${type} align="${token.align}">` + : `<${type}>`; + return tag + content + `\n`; + } + /** + * span level renderer + */ + strong({ tokens }) { + return `${this.parser.parseInline(tokens)}`; + } + em({ tokens }) { + return `${this.parser.parseInline(tokens)}`; + } + codespan({ text }) { + return `${text}`; + } + br(token) { + return '
    '; + } + del({ tokens }) { + return `${this.parser.parseInline(tokens)}`; + } + link({ href, title, tokens }) { + const text = this.parser.parseInline(tokens); + const cleanHref = cleanUrl(href); + if (cleanHref === null) { + return text; + } + href = cleanHref; + let out = '
    '; + return out; } - - // ignore IDs - return "" + text + "\n"; - }; - _proto.hr = function hr() { - return this.options.xhtml ? '
    \n' : '
    \n'; - }; - _proto.list = function list(body, ordered, start) { - var type = ordered ? 'ol' : 'ul', - startatt = ordered && start !== 1 ? ' start="' + start + '"' : ''; - return '<' + type + startatt + '>\n' + body + '\n'; - } - - /** - * @param {string} text - */; - _proto.listitem = function listitem(text) { - return "
  • " + text + "
  • \n"; - }; - _proto.checkbox = function checkbox(checked) { - return ' '; - } - - /** - * @param {string} text - */; - _proto.paragraph = function paragraph(text) { - return "

    " + text + "

    \n"; - } - - /** - * @param {string} header - * @param {string} body - */; - _proto.table = function table(header, body) { - if (body) body = "" + body + ""; - return '\n' + '\n' + header + '\n' + body + '
    \n'; - } - - /** - * @param {string} content - */; - _proto.tablerow = function tablerow(content) { - return "\n" + content + "\n"; - }; - _proto.tablecell = function tablecell(content, flags) { - var type = flags.header ? 'th' : 'td'; - var tag = flags.align ? "<" + type + " align=\"" + flags.align + "\">" : "<" + type + ">"; - return tag + content + ("\n"); - } - - /** - * span level renderer - * @param {string} text - */; - _proto.strong = function strong(text) { - return "" + text + ""; - } - - /** - * @param {string} text - */; - _proto.em = function em(text) { - return "" + text + ""; - } - - /** - * @param {string} text - */; - _proto.codespan = function codespan(text) { - return "" + text + ""; - }; - _proto.br = function br() { - return this.options.xhtml ? '
    ' : '
    '; - } - - /** - * @param {string} text - */; - _proto.del = function del(text) { - return "" + text + ""; - } - - /** - * @param {string} href - * @param {string} title - * @param {string} text - */; - _proto.link = function link(href, title, text) { - href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); - if (href === null) { - return text; - } - var out = '
    '; - return out; - } - - /** - * @param {string} href - * @param {string} title - * @param {string} text - */; - _proto.image = function image(href, title, text) { - href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); - if (href === null) { - return text; - } - var out = "\""' : '>'; - return out; - }; - _proto.text = function text(_text) { - return _text; - }; - return Renderer; - }(); + image({ href, title, text }) { + const cleanHref = cleanUrl(href); + if (cleanHref === null) { + return text; + } + href = cleanHref; + let out = `${text}/ig, '') - // remove unwanted chars - .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '').replace(/\s/g, '-'); - } - - /** - * Finds the next safe (unique) slug to use - * @param {string} originalSlug - * @param {boolean} isDryRun - */; - _proto.getNextSafeSlug = function getNextSafeSlug(originalSlug, isDryRun) { - var slug = originalSlug; - var occurenceAccumulator = 0; - if (this.seen.hasOwnProperty(slug)) { - occurenceAccumulator = this.seen[originalSlug]; - do { - occurenceAccumulator++; - slug = originalSlug + '-' + occurenceAccumulator; - } while (this.seen.hasOwnProperty(slug)); - } - if (!isDryRun) { - this.seen[originalSlug] = occurenceAccumulator; - this.seen[slug] = 0; - } - return slug; - } - - /** - * Convert string to unique id - * @param {object} [options] - * @param {boolean} [options.dryrun] Generates the next unique slug without - * updating the internal accumulator. - */; - _proto.slug = function slug(value, options) { - if (options === void 0) { - options = {}; - } - var slug = this.serialize(value); - return this.getNextSafeSlug(slug, options.dryrun); - }; - return Slugger; - }(); + class _TextRenderer { + // no need for block level renderers + strong({ text }) { + return text; + } + em({ text }) { + return text; + } + codespan({ text }) { + return text; + } + del({ text }) { + return text; + } + html({ text }) { + return text; + } + text({ text }) { + return text; + } + link({ text }) { + return '' + text; + } + image({ text }) { + return '' + text; + } + br() { + return ''; + } + } /** * Parsing & Compiling */ - var Parser = /*#__PURE__*/function () { - function Parser(options) { - this.options = options || exports.defaults; - this.options.renderer = this.options.renderer || new Renderer(); - this.renderer = this.options.renderer; - this.renderer.options = this.options; - this.textRenderer = new TextRenderer(); - this.slugger = new Slugger(); - } - - /** - * Static Parse Method - */ - Parser.parse = function parse(tokens, options) { - var parser = new Parser(options); - return parser.parse(tokens); - } - - /** - * Static Parse Inline Method - */; - Parser.parseInline = function parseInline(tokens, options) { - var parser = new Parser(options); - return parser.parseInline(tokens); - } - - /** - * Parse Loop - */; - var _proto = Parser.prototype; - _proto.parse = function parse(tokens, top) { - if (top === void 0) { - top = true; - } - var out = '', - i, - j, - k, - l2, - l3, - row, - cell, - header, - body, - token, - ordered, - start, - loose, - itemBody, - item, - checked, - task, - checkbox, - ret; - var l = tokens.length; - for (i = 0; i < l; i++) { - token = tokens[i]; - - // Run any renderer extensions - if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { - ret = this.options.extensions.renderers[token.type].call({ - parser: this - }, token); - if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) { - out += ret || ''; - continue; - } - } - switch (token.type) { - case 'space': - { - continue; - } - case 'hr': - { - out += this.renderer.hr(); - continue; - } - case 'heading': - { - out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger); - continue; - } - case 'code': - { - out += this.renderer.code(token.text, token.lang, token.escaped); - continue; - } - case 'table': - { - header = ''; - - // header - cell = ''; - l2 = token.header.length; - for (j = 0; j < l2; j++) { - cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), { - header: true, - align: token.align[j] - }); - } - header += this.renderer.tablerow(cell); - body = ''; - l2 = token.rows.length; - for (j = 0; j < l2; j++) { - row = token.rows[j]; - cell = ''; - l3 = row.length; - for (k = 0; k < l3; k++) { - cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { - header: false, - align: token.align[k] - }); - } - body += this.renderer.tablerow(cell); - } - out += this.renderer.table(header, body); - continue; - } - case 'blockquote': - { - body = this.parse(token.tokens); - out += this.renderer.blockquote(body); - continue; - } - case 'list': - { - ordered = token.ordered; - start = token.start; - loose = token.loose; - l2 = token.items.length; - body = ''; - for (j = 0; j < l2; j++) { - item = token.items[j]; - checked = item.checked; - task = item.task; - itemBody = ''; - if (item.task) { - checkbox = this.renderer.checkbox(checked); - if (loose) { - if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { - item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; - if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { - item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + class _Parser { + options; + renderer; + textRenderer; + constructor(options) { + this.options = options || exports.defaults; + this.options.renderer = this.options.renderer || new _Renderer(); + this.renderer = this.options.renderer; + this.renderer.options = this.options; + this.renderer.parser = this; + this.textRenderer = new _TextRenderer(); + } + /** + * Static Parse Method + */ + static parse(tokens, options) { + const parser = new _Parser(options); + return parser.parse(tokens); + } + /** + * Static Parse Inline Method + */ + static parseInline(tokens, options) { + const parser = new _Parser(options); + return parser.parseInline(tokens); + } + /** + * Parse Loop + */ + parse(tokens, top = true) { + let out = ''; + for (let i = 0; i < tokens.length; i++) { + const anyToken = tokens[i]; + // Run any renderer extensions + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) { + const genericToken = anyToken; + const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken); + if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) { + out += ret || ''; + continue; + } + } + const token = anyToken; + switch (token.type) { + case 'space': { + out += this.renderer.space(token); + continue; + } + case 'hr': { + out += this.renderer.hr(token); + continue; + } + case 'heading': { + out += this.renderer.heading(token); + continue; + } + case 'code': { + out += this.renderer.code(token); + continue; + } + case 'table': { + out += this.renderer.table(token); + continue; + } + case 'blockquote': { + out += this.renderer.blockquote(token); + continue; + } + case 'list': { + out += this.renderer.list(token); + continue; + } + case 'html': { + out += this.renderer.html(token); + continue; + } + case 'paragraph': { + out += this.renderer.paragraph(token); + continue; + } + case 'text': { + let textToken = token; + let body = this.renderer.text(textToken); + while (i + 1 < tokens.length && tokens[i + 1].type === 'text') { + textToken = tokens[++i]; + body += '\n' + this.renderer.text(textToken); } - } else { - item.tokens.unshift({ - type: 'text', - text: checkbox - }); - } - } else { - itemBody += checkbox; - } - } - itemBody += this.parse(item.tokens, loose); - body += this.renderer.listitem(itemBody, task, checked); - } - out += this.renderer.list(body, ordered, start); - continue; - } - case 'html': - { - out += this.renderer.html(token.text, token.block); - continue; - } - case 'paragraph': - { - out += this.renderer.paragraph(this.parseInline(token.tokens)); - continue; - } - case 'text': - { - body = token.tokens ? this.parseInline(token.tokens) : token.text; - while (i + 1 < l && tokens[i + 1].type === 'text') { - token = tokens[++i]; - body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text); - } - out += top ? this.renderer.paragraph(body) : body; - continue; - } - default: - { - var errMsg = 'Token with "' + token.type + '" type was not found.'; - if (this.options.silent) { - console.error(errMsg); - return; - } else { - throw new Error(errMsg); - } - } - } - } - return out; - } - - /** - * Parse Inline Tokens - */; - _proto.parseInline = function parseInline(tokens, renderer) { - renderer = renderer || this.renderer; - var out = '', - i, - token, - ret; - var l = tokens.length; - for (i = 0; i < l; i++) { - token = tokens[i]; - - // Run any renderer extensions - if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { - ret = this.options.extensions.renderers[token.type].call({ - parser: this - }, token); - if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) { - out += ret || ''; - continue; - } - } - switch (token.type) { - case 'escape': - { - out += renderer.text(token.text); - break; - } - case 'html': - { - out += renderer.html(token.text); - break; - } - case 'link': - { - out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer)); - break; - } - case 'image': - { - out += renderer.image(token.href, token.title, token.text); - break; - } - case 'strong': - { - out += renderer.strong(this.parseInline(token.tokens, renderer)); - break; - } - case 'em': - { - out += renderer.em(this.parseInline(token.tokens, renderer)); - break; - } - case 'codespan': - { - out += renderer.codespan(token.text); - break; - } - case 'br': - { - out += renderer.br(); - break; - } - case 'del': - { - out += renderer.del(this.parseInline(token.tokens, renderer)); - break; - } - case 'text': - { - out += renderer.text(token.text); - break; - } - default: - { - var errMsg = 'Token with "' + token.type + '" type was not found.'; - if (this.options.silent) { - console.error(errMsg); - return; - } else { - throw new Error(errMsg); - } - } - } - } - return out; - }; - return Parser; - }(); - - var Hooks = /*#__PURE__*/function () { - function Hooks(options) { - this.options = options || exports.defaults; - } - var _proto = Hooks.prototype; - /** - * Process markdown before marked - */ - _proto.preprocess = function preprocess(markdown) { - return markdown; - } - - /** - * Process HTML after marked is finished - */; - _proto.postprocess = function postprocess(html) { - return html; - }; - return Hooks; - }(); - Hooks.passThroughHooks = new Set(['preprocess', 'postprocess']); + if (top) { + out += this.renderer.paragraph({ + type: 'paragraph', + raw: body, + text: body, + tokens: [{ type: 'text', raw: body, text: body }], + }); + } + else { + out += body; + } + continue; + } + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.'; + if (this.options.silent) { + console.error(errMsg); + return ''; + } + else { + throw new Error(errMsg); + } + } + } + } + return out; + } + /** + * Parse Inline Tokens + */ + parseInline(tokens, renderer) { + renderer = renderer || this.renderer; + let out = ''; + for (let i = 0; i < tokens.length; i++) { + const anyToken = tokens[i]; + // Run any renderer extensions + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) { + const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken); + if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) { + out += ret || ''; + continue; + } + } + const token = anyToken; + switch (token.type) { + case 'escape': { + out += renderer.text(token); + break; + } + case 'html': { + out += renderer.html(token); + break; + } + case 'link': { + out += renderer.link(token); + break; + } + case 'image': { + out += renderer.image(token); + break; + } + case 'strong': { + out += renderer.strong(token); + break; + } + case 'em': { + out += renderer.em(token); + break; + } + case 'codespan': { + out += renderer.codespan(token); + break; + } + case 'br': { + out += renderer.br(token); + break; + } + case 'del': { + out += renderer.del(token); + break; + } + case 'text': { + out += renderer.text(token); + break; + } + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.'; + if (this.options.silent) { + console.error(errMsg); + return ''; + } + else { + throw new Error(errMsg); + } + } + } + } + return out; + } + } - function onError(silent, async, callback) { - return function (e) { - e.message += '\nPlease report this to https://github.com/markedjs/marked.'; - if (silent) { - var msg = '

    An error occurred:

    ' + escape(e.message + '', true) + '
    '; - if (async) { - return Promise.resolve(msg); - } - if (callback) { - callback(null, msg); - return; - } - return msg; - } - if (async) { - return Promise.reject(e); - } - if (callback) { - callback(e); - return; - } - throw e; - }; + class _Hooks { + options; + constructor(options) { + this.options = options || exports.defaults; + } + static passThroughHooks = new Set([ + 'preprocess', + 'postprocess', + 'processAllTokens', + ]); + /** + * Process markdown before marked + */ + preprocess(markdown) { + return markdown; + } + /** + * Process HTML after marked is finished + */ + postprocess(html) { + return html; + } + /** + * Process all tokens before walk tokens + */ + processAllTokens(tokens) { + return tokens; + } } - function parseMarkdown(lexer, parser) { - return function (src, opt, callback) { - if (typeof opt === 'function') { - callback = opt; - opt = null; - } - var origOpt = _extends({}, opt); - opt = _extends({}, marked.defaults, origOpt); - var throwError = onError(opt.silent, opt.async, callback); - // throw error in case of non string input - if (typeof src === 'undefined' || src === null) { - return throwError(new Error('marked(): input parameter is undefined or null')); - } - if (typeof src !== 'string') { - return throwError(new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected')); - } - checkDeprecations(opt, callback); - if (opt.hooks) { - opt.hooks.options = opt; - } - if (callback) { - var highlight = opt.highlight; - var tokens; - try { - if (opt.hooks) { - src = opt.hooks.preprocess(src); - } - tokens = lexer(src, opt); - } catch (e) { - return throwError(e); - } - var done = function done(err) { - var out; - if (!err) { - try { - if (opt.walkTokens) { - marked.walkTokens(tokens, opt.walkTokens); - } - out = parser(tokens, opt); + class Marked { + defaults = _getDefaults(); + options = this.setOptions; + parse = this.#parseMarkdown(_Lexer.lex, _Parser.parse); + parseInline = this.#parseMarkdown(_Lexer.lexInline, _Parser.parseInline); + Parser = _Parser; + Renderer = _Renderer; + TextRenderer = _TextRenderer; + Lexer = _Lexer; + Tokenizer = _Tokenizer; + Hooks = _Hooks; + constructor(...args) { + this.use(...args); + } + /** + * Run callback for every token + */ + walkTokens(tokens, callback) { + let values = []; + for (const token of tokens) { + values = values.concat(callback.call(this, token)); + switch (token.type) { + case 'table': { + const tableToken = token; + for (const cell of tableToken.header) { + values = values.concat(this.walkTokens(cell.tokens, callback)); + } + for (const row of tableToken.rows) { + for (const cell of row) { + values = values.concat(this.walkTokens(cell.tokens, callback)); + } + } + break; + } + case 'list': { + const listToken = token; + values = values.concat(this.walkTokens(listToken.items, callback)); + break; + } + default: { + const genericToken = token; + if (this.defaults.extensions?.childTokens?.[genericToken.type]) { + this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => { + const tokens = genericToken[childTokens].flat(Infinity); + values = values.concat(this.walkTokens(tokens, callback)); + }); + } + else if (genericToken.tokens) { + values = values.concat(this.walkTokens(genericToken.tokens, callback)); + } + } + } + } + return values; + } + use(...args) { + const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} }; + args.forEach((pack) => { + // copy options to new object + const opts = { ...pack }; + // set async to true if it was set to true before + opts.async = this.defaults.async || opts.async || false; + // ==-- Parse "addon" extensions --== // + if (pack.extensions) { + pack.extensions.forEach((ext) => { + if (!ext.name) { + throw new Error('extension name required'); + } + if ('renderer' in ext) { // Renderer extensions + const prevRenderer = extensions.renderers[ext.name]; + if (prevRenderer) { + // Replace extension with func to run new extension but fall back if false + extensions.renderers[ext.name] = function (...args) { + let ret = ext.renderer.apply(this, args); + if (ret === false) { + ret = prevRenderer.apply(this, args); + } + return ret; + }; + } + else { + extensions.renderers[ext.name] = ext.renderer; + } + } + if ('tokenizer' in ext) { // Tokenizer Extensions + if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) { + throw new Error("extension level must be 'block' or 'inline'"); + } + const extLevel = extensions[ext.level]; + if (extLevel) { + extLevel.unshift(ext.tokenizer); + } + else { + extensions[ext.level] = [ext.tokenizer]; + } + if (ext.start) { // Function to check for start of token + if (ext.level === 'block') { + if (extensions.startBlock) { + extensions.startBlock.push(ext.start); + } + else { + extensions.startBlock = [ext.start]; + } + } + else if (ext.level === 'inline') { + if (extensions.startInline) { + extensions.startInline.push(ext.start); + } + else { + extensions.startInline = [ext.start]; + } + } + } + } + if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens + extensions.childTokens[ext.name] = ext.childTokens; + } + }); + opts.extensions = extensions; + } + // ==-- Parse "overwrite" extensions --== // + if (pack.renderer) { + const renderer = this.defaults.renderer || new _Renderer(this.defaults); + for (const prop in pack.renderer) { + if (!(prop in renderer)) { + throw new Error(`renderer '${prop}' does not exist`); + } + if (['options', 'parser'].includes(prop)) { + // ignore options property + continue; + } + const rendererProp = prop; + let rendererFunc = pack.renderer[rendererProp]; + if (!pack.useNewRenderer) { + // TODO: Remove this in next major version + rendererFunc = this.#convertRendererFunction(rendererFunc, rendererProp, renderer); + } + const prevRenderer = renderer[rendererProp]; + // Replace renderer with func to run extension, but fall back if false + renderer[rendererProp] = (...args) => { + let ret = rendererFunc.apply(renderer, args); + if (ret === false) { + ret = prevRenderer.apply(renderer, args); + } + return ret || ''; + }; + } + opts.renderer = renderer; + } + if (pack.tokenizer) { + const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults); + for (const prop in pack.tokenizer) { + if (!(prop in tokenizer)) { + throw new Error(`tokenizer '${prop}' does not exist`); + } + if (['options', 'rules', 'lexer'].includes(prop)) { + // ignore options, rules, and lexer properties + continue; + } + const tokenizerProp = prop; + const tokenizerFunc = pack.tokenizer[tokenizerProp]; + const prevTokenizer = tokenizer[tokenizerProp]; + // Replace tokenizer with func to run extension, but fall back if false + // @ts-expect-error cannot type tokenizer function dynamically + tokenizer[tokenizerProp] = (...args) => { + let ret = tokenizerFunc.apply(tokenizer, args); + if (ret === false) { + ret = prevTokenizer.apply(tokenizer, args); + } + return ret; + }; + } + opts.tokenizer = tokenizer; + } + // ==-- Parse Hooks extensions --== // + if (pack.hooks) { + const hooks = this.defaults.hooks || new _Hooks(); + for (const prop in pack.hooks) { + if (!(prop in hooks)) { + throw new Error(`hook '${prop}' does not exist`); + } + if (prop === 'options') { + // ignore options property + continue; + } + const hooksProp = prop; + const hooksFunc = pack.hooks[hooksProp]; + const prevHook = hooks[hooksProp]; + if (_Hooks.passThroughHooks.has(prop)) { + // @ts-expect-error cannot type hook function dynamically + hooks[hooksProp] = (arg) => { + if (this.defaults.async) { + return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => { + return prevHook.call(hooks, ret); + }); + } + const ret = hooksFunc.call(hooks, arg); + return prevHook.call(hooks, ret); + }; + } + else { + // @ts-expect-error cannot type hook function dynamically + hooks[hooksProp] = (...args) => { + let ret = hooksFunc.apply(hooks, args); + if (ret === false) { + ret = prevHook.apply(hooks, args); + } + return ret; + }; + } + } + opts.hooks = hooks; + } + // ==-- Parse WalkTokens extensions --== // + if (pack.walkTokens) { + const walkTokens = this.defaults.walkTokens; + const packWalktokens = pack.walkTokens; + opts.walkTokens = function (token) { + let values = []; + values.push(packWalktokens.call(this, token)); + if (walkTokens) { + values = values.concat(walkTokens.call(this, token)); + } + return values; + }; + } + this.defaults = { ...this.defaults, ...opts }; + }); + return this; + } + // TODO: Remove this in next major release + #convertRendererFunction(func, prop, renderer) { + switch (prop) { + case 'heading': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, renderer.parser.parseInline(token.tokens), token.depth, unescape(renderer.parser.parseInline(token.tokens, renderer.parser.textRenderer))); + }; + case 'code': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, token.text, token.lang, !!token.escaped); + }; + case 'table': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + let header = ''; + // header + let cell = ''; + for (let j = 0; j < token.header.length; j++) { + cell += this.tablecell({ + text: token.header[j].text, + tokens: token.header[j].tokens, + header: true, + align: token.align[j], + }); + } + header += this.tablerow({ text: cell }); + let body = ''; + for (let j = 0; j < token.rows.length; j++) { + const row = token.rows[j]; + cell = ''; + for (let k = 0; k < row.length; k++) { + cell += this.tablecell({ + text: row[k].text, + tokens: row[k].tokens, + header: false, + align: token.align[k], + }); + } + body += this.tablerow({ text: cell }); + } + return func.call(this, header, body); + }; + case 'blockquote': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + const body = this.parser.parse(token.tokens); + return func.call(this, body); + }; + case 'list': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + const ordered = token.ordered; + const start = token.start; + const loose = token.loose; + let body = ''; + for (let j = 0; j < token.items.length; j++) { + const item = token.items[j]; + const checked = item.checked; + const task = item.task; + let itemBody = ''; + if (item.task) { + const checkbox = this.checkbox({ checked: !!checked }); + if (loose) { + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + } + } + else { + item.tokens.unshift({ + type: 'text', + text: checkbox + ' ', + }); + } + } + else { + itemBody += checkbox + ' '; + } + } + itemBody += this.parser.parse(item.tokens, loose); + body += this.listitem({ + type: 'list_item', + raw: itemBody, + text: itemBody, + task, + checked: !!checked, + loose, + tokens: item.tokens, + }); + } + return func.call(this, body, ordered, start); + }; + case 'html': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, token.text, token.block); + }; + case 'paragraph': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, this.parser.parseInline(token.tokens)); + }; + case 'escape': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, token.text); + }; + case 'link': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, token.href, token.title, this.parser.parseInline(token.tokens)); + }; + case 'image': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, token.href, token.title, token.text); + }; + case 'strong': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, this.parser.parseInline(token.tokens)); + }; + case 'em': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, this.parser.parseInline(token.tokens)); + }; + case 'codespan': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, token.text); + }; + case 'del': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, this.parser.parseInline(token.tokens)); + }; + case 'text': + return function (token) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func.call(this, token.text); + }; + // do nothing + } + return func; + } + setOptions(opt) { + this.defaults = { ...this.defaults, ...opt }; + return this; + } + lexer(src, options) { + return _Lexer.lex(src, options ?? this.defaults); + } + parser(tokens, options) { + return _Parser.parse(tokens, options ?? this.defaults); + } + #parseMarkdown(lexer, parser) { + return (src, options) => { + const origOpt = { ...options }; + const opt = { ...this.defaults, ...origOpt }; + // Show warning if an extension set async to true but the parse was called with async: false + if (this.defaults.async === true && origOpt.async === false) { + if (!opt.silent) { + console.warn('marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored.'); + } + opt.async = true; + } + const throwError = this.#onError(!!opt.silent, !!opt.async); + // throw error in case of non string input + if (typeof src === 'undefined' || src === null) { + return throwError(new Error('marked(): input parameter is undefined or null')); + } + if (typeof src !== 'string') { + return throwError(new Error('marked(): input parameter is of type ' + + Object.prototype.toString.call(src) + ', string expected')); + } if (opt.hooks) { - out = opt.hooks.postprocess(out); - } - } catch (e) { - err = e; - } - } - opt.highlight = highlight; - return err ? throwError(err) : callback(null, out); - }; - if (!highlight || highlight.length < 3) { - return done(); - } - delete opt.highlight; - if (!tokens.length) return done(); - var pending = 0; - marked.walkTokens(tokens, function (token) { - if (token.type === 'code') { - pending++; - setTimeout(function () { - highlight(token.text, token.lang, function (err, code) { - if (err) { - return done(err); - } - if (code != null && code !== token.text) { - token.text = code; - token.escaped = true; - } - pending--; - if (pending === 0) { - done(); - } - }); - }, 0); - } - }); - if (pending === 0) { - done(); - } - return; - } - if (opt.async) { - return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src).then(function (src) { - return lexer(src, opt); - }).then(function (tokens) { - return opt.walkTokens ? Promise.all(marked.walkTokens(tokens, opt.walkTokens)).then(function () { - return tokens; - }) : tokens; - }).then(function (tokens) { - return parser(tokens, opt); - }).then(function (html) { - return opt.hooks ? opt.hooks.postprocess(html) : html; - })["catch"](throwError); + opt.hooks.options = opt; + } + if (opt.async) { + return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src) + .then(src => lexer(src, opt)) + .then(tokens => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens) + .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens) + .then(tokens => parser(tokens, opt)) + .then(html => opt.hooks ? opt.hooks.postprocess(html) : html) + .catch(throwError); + } + try { + if (opt.hooks) { + src = opt.hooks.preprocess(src); + } + let tokens = lexer(src, opt); + if (opt.hooks) { + tokens = opt.hooks.processAllTokens(tokens); + } + if (opt.walkTokens) { + this.walkTokens(tokens, opt.walkTokens); + } + let html = parser(tokens, opt); + if (opt.hooks) { + html = opt.hooks.postprocess(html); + } + return html; + } + catch (e) { + return throwError(e); + } + }; + } + #onError(silent, async) { + return (e) => { + e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + if (silent) { + const msg = '

    An error occurred:

    '
    +                      + escape$1(e.message + '', true)
    +                      + '
    '; + if (async) { + return Promise.resolve(msg); + } + return msg; + } + if (async) { + return Promise.reject(e); + } + throw e; + }; } - try { - if (opt.hooks) { - src = opt.hooks.preprocess(src); - } - var _tokens = lexer(src, opt); - if (opt.walkTokens) { - marked.walkTokens(_tokens, opt.walkTokens); - } - var html = parser(_tokens, opt); - if (opt.hooks) { - html = opt.hooks.postprocess(html); - } - return html; - } catch (e) { - return throwError(e); - } - }; } + const markedInstance = new Marked(); + function marked(src, opt) { + return markedInstance.parse(src, opt); + } /** - * Marked + * Sets the default options. + * + * @param options Hash of options */ - function marked(src, opt, callback) { - return parseMarkdown(Lexer.lex, Parser.parse)(src, opt, callback); - } - + marked.options = + marked.setOptions = function (options) { + markedInstance.setOptions(options); + marked.defaults = markedInstance.defaults; + changeDefaults(marked.defaults); + return marked; + }; /** - * Options + * Gets the original marked default options. */ - - marked.options = marked.setOptions = function (opt) { - marked.defaults = _extends({}, marked.defaults, opt); - changeDefaults(marked.defaults); - return marked; - }; - marked.getDefaults = getDefaults; + marked.getDefaults = _getDefaults; marked.defaults = exports.defaults; - /** * Use Extension */ - - marked.use = function () { - var extensions = marked.defaults.extensions || { - renderers: {}, - childTokens: {} - }; - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - args.forEach(function (pack) { - // copy options to new object - var opts = _extends({}, pack); - - // set async to true if it was set to true before - opts.async = marked.defaults.async || opts.async || false; - - // ==-- Parse "addon" extensions --== // - if (pack.extensions) { - pack.extensions.forEach(function (ext) { - if (!ext.name) { - throw new Error('extension name required'); - } - if (ext.renderer) { - // Renderer extensions - var prevRenderer = extensions.renderers[ext.name]; - if (prevRenderer) { - // Replace extension with func to run new extension but fall back if false - extensions.renderers[ext.name] = function () { - for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } - var ret = ext.renderer.apply(this, args); - if (ret === false) { - ret = prevRenderer.apply(this, args); - } - return ret; - }; - } else { - extensions.renderers[ext.name] = ext.renderer; - } - } - if (ext.tokenizer) { - // Tokenizer Extensions - if (!ext.level || ext.level !== 'block' && ext.level !== 'inline') { - throw new Error("extension level must be 'block' or 'inline'"); - } - if (extensions[ext.level]) { - extensions[ext.level].unshift(ext.tokenizer); - } else { - extensions[ext.level] = [ext.tokenizer]; - } - if (ext.start) { - // Function to check for start of token - if (ext.level === 'block') { - if (extensions.startBlock) { - extensions.startBlock.push(ext.start); - } else { - extensions.startBlock = [ext.start]; - } - } else if (ext.level === 'inline') { - if (extensions.startInline) { - extensions.startInline.push(ext.start); - } else { - extensions.startInline = [ext.start]; - } - } - } - } - if (ext.childTokens) { - // Child tokens to be visited by walkTokens - extensions.childTokens[ext.name] = ext.childTokens; - } - }); - opts.extensions = extensions; - } - - // ==-- Parse "overwrite" extensions --== // - if (pack.renderer) { - var renderer = marked.defaults.renderer || new Renderer(); - var _loop = function _loop(prop) { - var prevRenderer = renderer[prop]; - // Replace renderer with func to run extension, but fall back if false - renderer[prop] = function () { - for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { - args[_key3] = arguments[_key3]; - } - var ret = pack.renderer[prop].apply(renderer, args); - if (ret === false) { - ret = prevRenderer.apply(renderer, args); - } - return ret; - }; - }; - for (var prop in pack.renderer) { - _loop(prop); - } - opts.renderer = renderer; - } - if (pack.tokenizer) { - var tokenizer = marked.defaults.tokenizer || new Tokenizer(); - var _loop2 = function _loop2(_prop) { - var prevTokenizer = tokenizer[_prop]; - // Replace tokenizer with func to run extension, but fall back if false - tokenizer[_prop] = function () { - for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { - args[_key4] = arguments[_key4]; - } - var ret = pack.tokenizer[_prop].apply(tokenizer, args); - if (ret === false) { - ret = prevTokenizer.apply(tokenizer, args); - } - return ret; - }; - }; - for (var _prop in pack.tokenizer) { - _loop2(_prop); - } - opts.tokenizer = tokenizer; - } - - // ==-- Parse Hooks extensions --== // - if (pack.hooks) { - var hooks = marked.defaults.hooks || new Hooks(); - var _loop3 = function _loop3(_prop2) { - var prevHook = hooks[_prop2]; - if (Hooks.passThroughHooks.has(_prop2)) { - hooks[_prop2] = function (arg) { - if (marked.defaults.async) { - return Promise.resolve(pack.hooks[_prop2].call(hooks, arg)).then(function (ret) { - return prevHook.call(hooks, ret); - }); - } - var ret = pack.hooks[_prop2].call(hooks, arg); - return prevHook.call(hooks, ret); - }; - } else { - hooks[_prop2] = function () { - for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { - args[_key5] = arguments[_key5]; - } - var ret = pack.hooks[_prop2].apply(hooks, args); - if (ret === false) { - ret = prevHook.apply(hooks, args); - } - return ret; - }; - } - }; - for (var _prop2 in pack.hooks) { - _loop3(_prop2); - } - opts.hooks = hooks; - } - - // ==-- Parse WalkTokens extensions --== // - if (pack.walkTokens) { - var _walkTokens = marked.defaults.walkTokens; - opts.walkTokens = function (token) { - var values = []; - values.push(pack.walkTokens.call(this, token)); - if (_walkTokens) { - values = values.concat(_walkTokens.call(this, token)); - } - return values; - }; - } - marked.setOptions(opts); - }); + marked.use = function (...args) { + markedInstance.use(...args); + marked.defaults = markedInstance.defaults; + changeDefaults(marked.defaults); + return marked; }; - /** * Run callback for every token */ - marked.walkTokens = function (tokens, callback) { - var values = []; - var _loop4 = function _loop4() { - var token = _step.value; - values = values.concat(callback.call(marked, token)); - switch (token.type) { - case 'table': - { - for (var _iterator2 = _createForOfIteratorHelperLoose(token.header), _step2; !(_step2 = _iterator2()).done;) { - var cell = _step2.value; - values = values.concat(marked.walkTokens(cell.tokens, callback)); - } - for (var _iterator3 = _createForOfIteratorHelperLoose(token.rows), _step3; !(_step3 = _iterator3()).done;) { - var row = _step3.value; - for (var _iterator4 = _createForOfIteratorHelperLoose(row), _step4; !(_step4 = _iterator4()).done;) { - var _cell = _step4.value; - values = values.concat(marked.walkTokens(_cell.tokens, callback)); - } - } - break; - } - case 'list': - { - values = values.concat(marked.walkTokens(token.items, callback)); - break; - } - default: - { - if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { - // Walk any extensions - marked.defaults.extensions.childTokens[token.type].forEach(function (childTokens) { - values = values.concat(marked.walkTokens(token[childTokens], callback)); - }); - } else if (token.tokens) { - values = values.concat(marked.walkTokens(token.tokens, callback)); - } - } - } - }; - for (var _iterator = _createForOfIteratorHelperLoose(tokens), _step; !(_step = _iterator()).done;) { - _loop4(); - } - return values; + return markedInstance.walkTokens(tokens, callback); }; - /** - * Parse Inline - * @param {string} src + * Compiles markdown to HTML without enclosing `p` tag. + * + * @param src String of markdown source to be compiled + * @param options Hash of options + * @return String of compiled HTML */ - marked.parseInline = parseMarkdown(Lexer.lexInline, Parser.parseInline); - + marked.parseInline = markedInstance.parseInline; /** * Expose */ - marked.Parser = Parser; - marked.parser = Parser.parse; - marked.Renderer = Renderer; - marked.TextRenderer = TextRenderer; - marked.Lexer = Lexer; - marked.lexer = Lexer.lex; - marked.Tokenizer = Tokenizer; - marked.Slugger = Slugger; - marked.Hooks = Hooks; + marked.Parser = _Parser; + marked.parser = _Parser.parse; + marked.Renderer = _Renderer; + marked.TextRenderer = _TextRenderer; + marked.Lexer = _Lexer; + marked.lexer = _Lexer.lex; + marked.Tokenizer = _Tokenizer; + marked.Hooks = _Hooks; marked.parse = marked; - var options = marked.options; - var setOptions = marked.setOptions; - var use = marked.use; - var walkTokens = marked.walkTokens; - var parseInline = marked.parseInline; - var parse = marked; - var parser = Parser.parse; - var lexer = Lexer.lex; - - exports.Hooks = Hooks; - exports.Lexer = Lexer; - exports.Parser = Parser; - exports.Renderer = Renderer; - exports.Slugger = Slugger; - exports.TextRenderer = TextRenderer; - exports.Tokenizer = Tokenizer; - exports.getDefaults = getDefaults; + const options = marked.options; + const setOptions = marked.setOptions; + const use = marked.use; + const walkTokens = marked.walkTokens; + const parseInline = marked.parseInline; + const parse = marked; + const parser = _Parser.parse; + const lexer = _Lexer.lex; + + exports.Hooks = _Hooks; + exports.Lexer = _Lexer; + exports.Marked = Marked; + exports.Parser = _Parser; + exports.Renderer = _Renderer; + exports.TextRenderer = _TextRenderer; + exports.Tokenizer = _Tokenizer; + exports.getDefaults = _getDefaults; exports.lexer = lexer; exports.marked = marked; exports.options = options; diff --git a/Resources/Translations/jaspDesktop-de.qm b/Resources/Translations/jaspDesktop-de.qm index b8ece41403..b46dc575d2 100644 Binary files a/Resources/Translations/jaspDesktop-de.qm and b/Resources/Translations/jaspDesktop-de.qm differ diff --git a/Resources/Translations/jaspDesktop-es.qm b/Resources/Translations/jaspDesktop-es.qm index 1712306f66..72ea577f20 100644 Binary files a/Resources/Translations/jaspDesktop-es.qm and b/Resources/Translations/jaspDesktop-es.qm differ diff --git a/Resources/Translations/jaspDesktop-gl.qm b/Resources/Translations/jaspDesktop-gl.qm index 684fa1abe4..4c407f6cf4 100644 Binary files a/Resources/Translations/jaspDesktop-gl.qm and b/Resources/Translations/jaspDesktop-gl.qm differ diff --git a/Resources/Translations/jaspDesktop-tr.qm b/Resources/Translations/jaspDesktop-tr.qm index 481bf2e565..8837fe70c1 100644 Binary files a/Resources/Translations/jaspDesktop-tr.qm and b/Resources/Translations/jaspDesktop-tr.qm differ diff --git a/Resources/Translations/jaspDesktop-zh_Hans.qm b/Resources/Translations/jaspDesktop-zh_Hans.qm index 8de387792f..b8c9d59d7b 100644 Binary files a/Resources/Translations/jaspDesktop-zh_Hans.qm and b/Resources/Translations/jaspDesktop-zh_Hans.qm differ diff --git a/Tools/CMake/FindRPackagePath.cmake b/Tools/CMake/FindRPackagePath.cmake new file mode 100644 index 0000000000..a83c7e80f6 --- /dev/null +++ b/Tools/CMake/FindRPackagePath.cmake @@ -0,0 +1,22 @@ + +# Locate the full paths (so those in the cache, not the symlinks) + +#Argh +if("${CMAKE_PROJECT_NAME}" STREQUAL "R-Interface") + set(FIND_PACKAGE_PATH_SCRIPT ${CMAKE_SOURCE_DIR}/../Tools/find_package_path.R) +else() + + set(FIND_PACKAGE_PATH_SCRIPT ${CMAKE_SOURCE_DIR}/Tools/find_package_path.R) +endif() + +macro(find_package_path out libPath packageName) + #We are not using Rscript anywhere in CMake because that doesn't work on macOs + execute_process( + COMMAND ${R_EXECUTABLE} --slave --file=${FIND_PACKAGE_PATH_SCRIPT} ${libPath} ${packageName} + OUTPUT_VARIABLE TEMP_OUT + COMMAND_ECHO STDOUT) + #R could be printing all sorts of bullshit, so instead we simply take the last line of output + message(STATUS "TEMP_OUT is ${TEMP_OUT}") + string(REGEX MATCHALL "[^\n\r]+" TEMPLINES ${TEMP_OUT}) + list(GET TEMPLINES -1 ${out}) +endmacro() diff --git a/Tools/CMake/Install.cmake b/Tools/CMake/Install.cmake index 560ad3b551..853644aee0 100644 --- a/Tools/CMake/Install.cmake +++ b/Tools/CMake/Install.cmake @@ -250,6 +250,11 @@ endif() install(FILES ${CMAKE_SOURCE_DIR}/Tools/flatpak/org.jaspstats.JASP.mime.xml DESTINATION ${JASP_INSTALL_PREFIX}/share/mime/packages) + + #clean up flatpak + if(FLATPAK_USED) + install(CODE "execute_process(COMMAND ${CMAKE_SOURCE_DIR}/Tools/flatpak/cleanFlatpak.sh WORKING_DIRECTORY ${CMAKE_BINARY_DIR})") + endif() endif() @@ -324,6 +329,9 @@ if(WIN32) configure_file(${CMAKE_SOURCE_DIR}/Tools/windows/msi/JASP.wxs ${CMAKE_BINARY_DIR}/JASP.wxs @ONLY) + configure_file(${CMAKE_SOURCE_DIR}/Tools/windows/exe/ExePackerScript.iss.in + ${CMAKE_BINARY_DIR}/ExePackerScript.iss @ONLY) + configure_file(${CMAKE_SOURCE_DIR}/Tools/windows/msi/WIX.cmd.in ${CMAKE_BINARY_DIR}/WIX.cmd @ONLY) @@ -333,12 +341,12 @@ if(WIN32) configure_file(${CMAKE_SOURCE_DIR}/Tools/windows/CollectJunctions.cmd.in ${CMAKE_BINARY_DIR}/CollectJunctions.cmd @ONLY) - configure_file(${CMAKE_SOURCE_DIR}/Tools/windows/windowsPreInstallHacks.cmd.in - ${CMAKE_BINARY_DIR}/windowsPreInstallHacks.cmd @ONLY) - configure_file(${CMAKE_SOURCE_DIR}/Tools/windows/RecreateJunctions.cmd.in ${CMAKE_BINARY_DIR}/RecreateJunctions.cmd @ONLY) + configure_file(${CMAKE_SOURCE_DIR}/Tools/windows/RecursiveJunctionRemover.cmd.in + ${CMAKE_BINARY_DIR}/RecursiveJunctionRemover.cmd @ONLY) + #msix stuff configure_file(${CMAKE_SOURCE_DIR}/Tools/windows/msix/AppxManifest-store.xml.in ${CMAKE_BINARY_DIR}/AppxManifest-store.xml @ONLY) @@ -371,29 +379,36 @@ if(WIN32) install(FILES ${CMAKE_SOURCE_DIR}/Desktop/icon.ico DESTINATION .) - install( - DIRECTORY ${CMAKE_BINARY_DIR}/Modules/renv-cache - DESTINATION Modules/ - REGEX ${FILES_EXCLUDE_PATTERN} EXCLUDE - REGEX ${FOLDERS_EXCLUDE_PATTERN} EXCLUDE) - install( FILES ${CMAKE_SOURCE_DIR}/R-Interface/R/workarounds.R ${CMAKE_SOURCE_DIR}/R-Interface/R/symlinkTools.R - DESTINATION Modules/) + DESTINATION Modules/Tools/) install( FILES ${RTOOLS_LIBGCC_S_SEH_DLL} ${RTOOLS_LIBSTDCPP_DLL} - ${RTOOLS_MSYS_DLL} + ${RTOOLS_MSYS_DLL} ${RTOOLS_LIBWINPTHREAD_DLL} - #${RTOOLS_LIBJSONCPP_DLL} - ${RTOOLS_LIBREADSTAT_DLL} + #${RTOOLS_LIBJSONCPP_DLL} + ${RTOOLS_LIBREADSTAT_DLL} ${RTOOLS_ZLIB_DLL} ${RTOOLS_LIBICONV_DLL} ${_LIB_R_INTERFACE_DLL} DESTINATION .) + install( + DIRECTORY ${CMAKE_BINARY_DIR}/Modules/renv-cache + DESTINATION Modules/ + REGEX ${FILES_EXCLUDE_PATTERN} EXCLUDE + REGEX ${FOLDERS_EXCLUDE_PATTERN} EXCLUDE) + + install( + DIRECTORY ${CMAKE_BINARY_DIR}/Modules/Tools/ + DESTINATION Modules/Tools + REGEX ${FILES_EXCLUDE_PATTERN} EXCLUDE + REGEX ${FOLDERS_EXCLUDE_PATTERN} EXCLUDE) + + install(CODE "execute_process(COMMAND cmd.exe /C ${CMAKE_BINARY_DIR}/RecursiveJunctionRemover.cmd)") endif() list(POP_BACK CMAKE_MESSAGE_CONTEXT) diff --git a/Tools/CMake/JASP.cmake b/Tools/CMake/JASP.cmake index c1314b1be0..79d4cc381e 100644 --- a/Tools/CMake/JASP.cmake +++ b/Tools/CMake/JASP.cmake @@ -65,13 +65,28 @@ set(MSIX_NIGHTLY_PUBLISHER CACHE STRING "Publisher set for nightly msix package") set(MSIX_SIGN_CERT_PATH - "D:\\JASPSelfSign.pfx" + "C:\\JASPSelfSign.pfx" CACHE STRING "Path to selfsign cert for Nightlies") set(MSIX_SIGN_CERT_PASSWORD "0000" CACHE STRING "Password selfsign cert for Nightlies") +set(R_PKG_CELLAR_PATH + "" + CACHE STRING "Set the path for an renv package cellar to be used during build phase") + +set(RPKG_DOWNLOAD_ONLY + OFF + CACHE BOOL "If enabled renv will not install JASP module deps but just download them. Usefull to make a cellar for Flatpak") + +set(REGENERATE_LOCKFILE + OFF + CACHE BOOL "If enabled jaspModuleInstaller will generate a fresh lockfile") + +set(MODULE_INSTALL_MODE + "localizeAll" + CACHE STRING "identicalToLockfile or localizeModuleOnly or localizeAll. Sets how much is pulled remote or from source folder") # TODO: # - [ ] Rename all JASP related variables to `JASP_*`. This way, @@ -84,8 +99,8 @@ if(NOT R_REPOSITORY) "http://cloud.r-project.org" CACHE STRING "The CRAN mirror used by 'renv' and 'install.packages'") endif() - if(FLATPAK_USED AND LINUX) + set(R_PKG_CELLAR_PATH "/app/lib64/cellar") set(R_REPOSITORY "file:///app/lib64/local-cran") endif() diff --git a/Tools/CMake/Libraries.cmake b/Tools/CMake/Libraries.cmake index cc4681a091..d61756db74 100644 --- a/Tools/CMake/Libraries.cmake +++ b/Tools/CMake/Libraries.cmake @@ -181,7 +181,7 @@ if(LINUX) set(LIBREADSTAT_INCLUDE_DIRS /usr/local/include /usr/include) # The last two library paths handle the two most common multiarch cases. # Other multiarch-compliant paths may come up but should be rare. - set(LIBREADSTAT_LIBRARY_DIRS /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/aarch64-linux-gnu) + set(LIBREADSTAT_LIBRARY_DIRS /usr/local/lib /usr/lib /usr/lib64 /usr/lib/x86_64-linux-gnu /usr/lib/aarch64-linux-gnu) endif() message(CHECK_START "Looking for libreadstat.so") @@ -199,6 +199,26 @@ if(LINUX) ) endif() + # ---- FreeXL ---- + message(CHECK_START "Looking for `libfreexl`") + set(LIBFREEXL_INCLUDE_DIRS /usr/include) + set(LIBFREEXL_LIBRARY_DIRS /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/aarch64-linux-gnu) + + message(CHECK_START "Looking for libfreexl.so") + find_library(LIBFREEXL_LIBRARIES libfreexl.so + HINTS ${LIBFREEXL_LIBRARY_DIRS} REQUIRED) + + if(EXISTS ${LIBFREEXL_LIBRARIES}) + message(CHECK_PASS "found") + message(STATUS " ${LIBFREEXL_LIBRARIES}") + else() + message(CHECK_FAIL "not found") + message( + FATAL_ERROR + "FreeXL is required for building on Linux, please follow the build instruction before you continue." + ) + endif() + find_package(PkgConfig) #pkg_check_modules(_PKGCONFIG_LIB_JSONCPP REQUIRED jsoncpp>=1.9) @@ -209,10 +229,14 @@ if(APPLE) message(CHECK_START "Looking for 'libbrotlicommon'") find_package(Brotli 1.0.9 REQUIRED) + find_package(freexl 2.0.0 REQUIRED) endif() if(WIN32) + + find_package(freexl 2.0.0 REQUIRED) + # ReadStat message(CHECK_START "Looking for libreadstat.dll.a") @@ -269,7 +293,6 @@ if(WIN32) ) endif() - message(CHECK_START "Looking for zlib1.dll") find_file( RTOOLS_ZLIB_DLL @@ -380,103 +403,6 @@ if(WIN32) ) endif() - #message(CHECK_START "Looking for libjsoncpp-24.dll") - #find_file( - # RTOOLS_LIBJSONCPP_DLL - # NAMES libjsoncpp-24.dll - # PATHS ${RTOOLS_PATH}/bin - # NO_DEFAULT_PATH) - - #if(EXISTS ${RTOOLS_LIBJSONCPP_DLL}) - # message(CHECK_PASS "found") - # message(STATUS " ${RTOOLS_LIBJSONCPP_DLL}") - #else() - # message(CHECK_FAIL "not found") - # message( - # FATAL_ERROR - # "MSYS2 and some of its libraries are required for building on Windows, please follow the build instruction before you continue." - # ) - #endif() - - # jags - # This could all go into its module later, and these can - # turn into a function, but I don't want to do it now - # because I'm uncertain about CMake variable scopping - # message(CHECK_START "Looking for jags files") - # find_file( - # RTOOLS_LIBJAGS_BAT - # NAMES jags.bat - # PATHS ${RTOOLS_PATH}/bin REQUIRED) - # message(STATUS " ${RTOOLS_LIBJAGS_BAT}") - # find_file( - # RTOOLS_LIBJAGS - # NAMES libjags-4.dll - # PATHS ${RTOOLS_PATH}/bin REQUIRED) - # message(STATUS " ${RTOOLS_LIBJAGS}") - # find_file( - # RTOOLS_LIBJAGS_JRMATH - # NAMES libjrmath-0.dll - # PATHS ${RTOOLS_PATH}/bin REQUIRED) - # message(STATUS " ${RTOOLS_LIBJAGS_JRMATH}") - # find_file( - # RTOOLS_LIB_BLAS - # NAMES libblas.dll - # PATHS ${RTOOLS_PATH}/bin REQUIRED) - # message(STATUS " ${RTOOLS_LIB_BLAS}") - # find_file( - # RTOOLS_LIB_LAPACK - # NAMES liblapack.dll - # PATHS ${RTOOLS_PATH}/bin REQUIRED) - # message(STATUS " ${RTOOLS_LIB_LAPACK}") - - # set(RTOOLS_LIBJAGS_HEADERS_PATH "${RTOOLS_PATH}/include/JAGS") - # message(STATUS " ${RTOOLS_LIBJAGS_HEADERS_PATH}") - # set(RTOOLS_LIBJAGS_LIBRARIES_PATH "${RTOOLS_PATH}/lib/JAGS") - # message(STATUS " ${RTOOLS_LIBJAGS_LIBRARIES_PATH}") - # set(RTOOLS_LIBJAGS_PKGCONFIG_PATH "${RTOOLS_PATH}/lib/pkgconfig") - # message(STATUS " ${RTOOLS_LIBJAGS_PKGCONFIG_PATH}") - # set(RTOOLS_LIBJAGS_MODULES_PATH "${RTOOLS_PATH}/lib/JAGS/modules-4") - # message(STATUS " ${RTOOLS_LIBJAGS_MODULES_PATH}") - - # find_file( - # RTOOLS_LIBJAGS_LIBJAGS_A - # NAMES libjags.dll.a - # PATHS ${RTOOLS_PATH}/lib REQUIRED) - # message(STATUS " ${RTOOLS_LIBJAGS_LIBJAGS_A}") - # find_file( - # RTOOLS_LIBJAGS_LIBJAGS_LA - # NAMES libjags.la - # PATHS ${RTOOLS_PATH}/lib REQUIRED) - # message(STATUS " ${RTOOLS_LIBJAGS_LIBJAGS_LA}") - # find_file( - # RTOOLS_LIBJAGS_LIBJRMATH_A - # NAMES libjrmath.dll.a - # PATHS ${RTOOLS_PATH}/lib REQUIRED) - # message(STATUS " ${RTOOLS_LIBJAGS_LIBJRMATH_A}") - # find_file( - # RTOOLS_LIBJAGS_LIBJRMATH_LA - # NAMES libjrmath.la - # PATHS ${RTOOLS_PATH}/lib REQUIRED) - # message(STATUS " ${RTOOLS_LIBJAGS_LIBJRMATH_LA}") - # find_file( - # RTOOLS_LIB_BLAS_DLL_A - # NAMES libblas.dll.a - # PATHS ${RTOOLS_PATH}/lib REQUIRED) - # message(STATUS " ${RTOOLS_LIB_BLAS_DLL_A}") - # find_file( - # RTOOLS_LIB_LAPACK_DLL_A - # NAMES liblapack.dll.a - # PATHS ${RTOOLS_PATH}/lib REQUIRED) - # message(STATUS " ${RTOOLS_LIB_LAPACK_DLL_A}") - - # find_file( - # RTOOLS_LIBJAGS_JAGS_TERMINAL_EXE - # NAMES jags-terminal.exe - # PATHS ${RTOOLS_PATH}/libexec REQUIRED) - # message(STATUS " ${RTOOLS_LIBJAGS_JAGS_TERMINAL_EXE}") - - # message(CHECK_PASS "found") - endif() list(POP_BACK CMAKE_MESSAGE_CONTEXT) diff --git a/Tools/CMake/Modules.cmake b/Tools/CMake/Modules.cmake index 44dde24bce..01514337dd 100644 --- a/Tools/CMake/Modules.cmake +++ b/Tools/CMake/Modules.cmake @@ -22,44 +22,45 @@ set(JASP_TEST_BUILD OFF CACHE BOOL "Do a quick build with just descriptive set(JASP_TEST_MODULE "jaspDescriptives" CACHE STRING "Which module other than jaspTestModule would you like to test?") if(NOT JASP_TEST_BUILD) - set(JASP_COMMON_MODULES - "jaspDescriptives" - "jaspTTests" - "jaspAnova" - "jaspMixedModels" - "jaspRegression" - "jaspFrequencies" - "jaspFactor" - ) - - set(JASP_EXTRA_MODULES - "jaspAcceptanceSampling" - "jaspAudit" - "jaspBain" - "jaspBsts" - "jaspCircular" - "jaspCochrane" - "jaspDistributions" - "jaspEquivalenceTTests" - "jaspJags" - "jaspLearnBayes" - "jaspLearnStats" - "jaspMachineLearning" - "jaspMetaAnalysis" - "jaspNetwork" - "jaspPower" - "jaspPredictiveAnalytics" - "jaspProcess" - "jaspProphet" - "jaspQualityControl" - "jaspReliability" - "jaspRobustTTests" - "jaspSem" - "jaspSurvival" - "jaspSummaryStatistics" - "jaspTimeSeries" - "jaspVisualModeling" - ) +set(JASP_COMMON_MODULES + "jaspDescriptives" + "jaspTTests" + "jaspAnova" + "jaspMixedModels" + "jaspRegression" + "jaspFrequencies" + "jaspFactor" +) + +set(JASP_EXTRA_MODULES + "jaspAcceptanceSampling" + "jaspAudit" + "jaspBain" + "jaspBFF" + "jaspBsts" + "jaspCircular" + "jaspCochrane" + "jaspDistributions" + "jaspEquivalenceTTests" + "jaspJags" + "jaspLearnBayes" + "jaspLearnStats" + "jaspMachineLearning" + "jaspMetaAnalysis" + "jaspNetwork" + "jaspPower" + "jaspPredictiveAnalytics" + "jaspProcess" + "jaspProphet" + "jaspQualityControl" + "jaspReliability" + "jaspRobustTTests" + "jaspSem" + "jaspSurvival" + "jaspSummaryStatistics" + "jaspTimeSeries" + "jaspVisualModeling" + ) else() #it IS a test build message(STATUS "JASP_TEST_BUILD is enabled, building with minimal modules") set(JASP_COMMON_MODULES @@ -152,42 +153,36 @@ message(STATUS "Installing Required R Modules...") execute_process( WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/R-Interface COMMAND ${CMAKE_COMMAND} -E copy_if_different R/workarounds.R - ${MODULES_BINARY_PATH}/ + ${MODULES_BINARY_PATH}/Tools/ COMMAND ${CMAKE_COMMAND} -E copy_if_different R/symlinkTools.R - ${MODULES_BINARY_PATH}/) + ${MODULES_BINARY_PATH}/Tools/) add_custom_target( - jaspBase + jaspModuleInstaller WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/R-Interface - DEPENDS ${MODULES_BINARY_PATH}/jaspBase/jaspBaseHash.rds) - -configure_file("${PROJECT_SOURCE_DIR}/Modules/install-jaspBase.R.in" - ${SCRIPT_DIRECTORY}/install-jaspBase.R @ONLY) - -# I'm using a custom_command here to make sure that jaspBase is installed once -# and only once before everything else. So, `install-jaspBase.R` creates an empty -# file, i.e., `jaspBase-installed-successfully.log` and all other Modules look for -# it. If they find it, they proceed, if not, they trigger this custom command. -# TODO: -# - [ ] The following commands can be turned into a function or a macro, but -# for now, I would like to keep a granular control over differnt steps + DEPENDS ${JASPMODULEINSTALLER_LIBRARY}/jaspModuleInstaller) + +configure_file("${PROJECT_SOURCE_DIR}/Modules/install-jaspModuleInstaller.R.in" + ${SCRIPT_DIRECTORY}/install-jaspModuleInstaller.R @ONLY) + +# I'm using a custom_command here to make sure that jaspModuleInstaller is installed once if(APPLE) - add_dependencies(jaspBase JASPEngine) + add_dependencies(jaspModuleInstaller JASPEngine) add_custom_command( WORKING_DIRECTORY ${R_HOME_PATH} - OUTPUT ${MODULES_BINARY_PATH}/jaspBase/jaspBaseHash.rds - USES_TERMINAL - COMMAND ${CMAKE_COMMAND} -E env "JASP_R_HOME=${R_HOME_PATH}" ${R_EXECUTABLE} --slave --no-restore --no-save --file=${SCRIPT_DIRECTORY}/install-jaspBase.R - COMMENT "------ Installing 'jaspBase'") + OUTPUT ${JASPMODULEINSTALLER_LIBRARY}/jaspModuleInstaller + USES_TERMINAL + COMMAND ${CMAKE_COMMAND} -E env "JASP_R_HOME=${R_HOME_PATH}" ${R_EXECUTABLE} --slave --no-restore --no-save --file=${SCRIPT_DIRECTORY}/install-jaspModuleInstaller.R + COMMENT "------ Installing 'jaspModuleInstaller'") else() add_custom_command( WORKING_DIRECTORY ${R_HOME_PATH} - OUTPUT ${R_HOME_PATH}/jaspBase_md5sums.rds + OUTPUT ${JASPMODULEINSTALLER_LIBRARY}/jaspModuleInstaller USES_TERMINAL COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save - --file=${SCRIPT_DIRECTORY}/install-jaspBase.R - COMMENT "------ Installing 'jaspBase'") + --file=${SCRIPT_DIRECTORY}/install-jaspModuleInstaller.R + COMMENT "------ Installing 'jaspModuleInstaller'") endif() @@ -221,7 +216,7 @@ if(APPLE) ${MODULE} USES_TERMINAL WORKING_DIRECTORY ${R_HOME_PATH} - DEPENDS ${MODULES_BINARY_PATH}/jaspBase/jaspBaseHash.rds + DEPENDS ${JASPMODULEINSTALLER_LIBRARY}/jaspModuleInstaller COMMAND ${CMAKE_COMMAND} -E env "JASP_R_HOME=${R_HOME_PATH}" ${R_EXECUTABLE} --slave --no-restore --no-save --file=${SCRIPT_DIRECTORY}/install-${MODULE}.R # COMMAND # ${CMAKE_COMMAND} -D PATH=${MODULES_BINARY_PATH}/${MODULE} -D @@ -239,7 +234,7 @@ else() ${MODULE} USES_TERMINAL WORKING_DIRECTORY ${R_HOME_PATH} - DEPENDS ${R_HOME_PATH}/jaspBase_md5sums.rds + DEPENDS ${JASPMODULEINSTALLER_LIBRARY}/jaspModuleInstaller COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save --file=${SCRIPT_DIRECTORY}/install-${MODULE}.R BYPRODUCTS ${MODULES_BINARY_PATH}/${MODULE} @@ -273,9 +268,7 @@ if(APPLE) ${MODULE} USES_TERMINAL WORKING_DIRECTORY ${R_HOME_PATH} - DEPENDS - JASPEngine - ${MODULES_BINARY_PATH}/jaspBase/jaspBaseHash.rds + DEPENDS JASPEngine ${JASPMODULEINSTALLER_LIBRARY}/jaspModuleInstaller $<$:${jags_VERSION_H_PATH}> $<$:${jags_VERSION_H_PATH}> COMMAND ${CMAKE_COMMAND} -E env "JASP_R_HOME=${R_HOME_PATH}" ${R_EXECUTABLE} --slave --no-restore --no-save --file=${SCRIPT_DIRECTORY}/install-${MODULE}.R @@ -293,10 +286,7 @@ else() ${MODULE} USES_TERMINAL WORKING_DIRECTORY ${R_HOME_PATH} - DEPENDS - ${R_HOME_PATH}/jaspBase_md5sums.rds - $<$:${jags_VERSION_H_PATH}> - $<$:${jags_VERSION_H_PATH}> + DEPENDS ${JASPMODULEINSTALLER_LIBRARY}/jaspModuleInstaller $<$:${jags_VERSION_H_PATH}> $<$:${jags_VERSION_H_PATH}> COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save --file=${SCRIPT_DIRECTORY}/install-${MODULE}.R diff --git a/Tools/CMake/Pack.cmake b/Tools/CMake/Pack.cmake index ca22e7b5e2..7d6cf2ef8e 100644 --- a/Tools/CMake/Pack.cmake +++ b/Tools/CMake/Pack.cmake @@ -58,12 +58,6 @@ if(WIN32) configure_file(${CMAKE_SOURCE_DIR}/Tools/windows/Upload.cmd.in ${CMAKE_BINARY_DIR}/Upload.cmd @ONLY) - add_custom_target( - windowsPreInstallHacks - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - COMMAND cmd.exe /C windowsPreInstallHacks.cmd - ) - add_custom_target( collect-junctions WORKING_DIRECTORY ${PROJECT_BINARY_DIR} diff --git a/Tools/CMake/Patch.cmake b/Tools/CMake/Patch.cmake index 4b21f15165..7c72700c95 100644 --- a/Tools/CMake/Patch.cmake +++ b/Tools/CMake/Patch.cmake @@ -42,7 +42,7 @@ else() file( GLOB_RECURSE LIBRARIES - #FOLLOW_SYMLINKS #Turned this off because it got infinitely regressed + FOLLOW_SYMLINKS #Don turned this off because it got infinitely regressed, but Joris turned it back on because we use symlinks to go to packages nowadays... "${PATH}/*.so" "${PATH}/*.dylib") list( @@ -69,6 +69,9 @@ else() ${LIBRARIES} ${BINARIES}) + + message(STATUS "* Patching got files: ${Files}") + set(NEW_ID "") set(FRAMEWORK_RESOURCES "@executable_path/../Frameworks/R.framework/Versions/${R_DIR_NAME}/Resources") @@ -77,6 +80,9 @@ else() get_filename_component(FILE_NAME ${FILE} NAME) get_filename_component(DIRECTORY_NAME ${FILE} DIRECTORY) + message(STATUS "** Patching in Dir '$DIRECTORY' the file '${FILE}'") + + string(LENGTH "${PATH}/" PATH_LENGTH) string( SUBSTRING "${FILE}" diff --git a/Tools/CMake/Programs.cmake b/Tools/CMake/Programs.cmake index ca257375f6..bfdc8dc63c 100644 --- a/Tools/CMake/Programs.cmake +++ b/Tools/CMake/Programs.cmake @@ -166,12 +166,11 @@ if(WIN32) ) endif() - set(WIX_PATH - "C:/Program Files (x86)/WiX Toolset v3.11/bin" - CACHE - PATH - "Path to your WIX installation, e.g., C:\\Program Files (x86)\\WiX Toolset v3.11\\bin" - ) + if(DEFINED ENV{WIX}) + set(WIX_PATH "$ENV{WIX}/bin" CACHE PATH "Path to your WIX installation, e.g., C:\\Program Files (x86)\\WiX Toolset v3.11\\bin") + else() + set(WIX_PATH "C:/Program Files (x86)/WiX Toolset v3.11/bin" CACHE PATH "Path to your WIX installation, e.g., C:\\Program Files (x86)\\WiX Toolset v3.11\\bin") + endif() find_program( HEAT_EXECUTABLE diff --git a/Tools/CMake/R.cmake b/Tools/CMake/R.cmake index a010425788..0df6f7c3d9 100644 --- a/Tools/CMake/R.cmake +++ b/Tools/CMake/R.cmake @@ -16,15 +16,15 @@ # on x86_64, it is using the Fortran 8. # # Notes: -# - Be aware that at some point, R will move to use a different Fortran, and +# - Be aware that at some point, R will move to use a different Fortran, and # when that happens, someone needs to make sure that the right Fortran is being -# download, unpacked, and placed in the right location. You can find the +# download, unpacked, and placed in the right location. You can find the # appropriate version in `etc/Makeconf` and the binary here, # https://github.com/fxcoudert/gfortran-for-macOS/releases # - On GitHub Action, # - You probably want to unpack the `https://static.jasp-stats.org/development/gfortran-8.2-Mojave.dmg` # into a `.tar.gz`. I think this might elimite some possible issues with the unpacking on -# their environment. If you have decided to do this, make sure that the structure of the +# their environment. If you have decided to do this, make sure that the structure of the # archive is similiar and things land where they are expected. # # Todos: @@ -203,18 +203,17 @@ cmake_print_variables(MODULES_RENV_CACHE_PATH) if(APPLE) - set(R_FRAMEWORK_PATH "${CMAKE_BINARY_DIR}/Frameworks") - set(R_HOME_PATH - "${R_FRAMEWORK_PATH}/R.framework/Versions/${R_DIR_NAME}/Resources") - set(R_LIBRARY_PATH "${R_HOME_PATH}/library") - set(R_OPT_PATH "${R_HOME_PATH}/opt") - set(R_EXECUTABLE "${R_HOME_PATH}/bin/R") - set(R_INCLUDE_PATH "${R_HOME_PATH}/include") - set(RCPP_PATH "${R_LIBRARY_PATH}/Rcpp") - set(RINSIDE_PATH "${R_LIBRARY_PATH}/RInside") - set(RENV_PATH "${R_LIBRARY_PATH}/renv") - set(ENV{JASP_R_HOME} ${R_HOME_PATH}) - set(ENV{R_HOME} ${R_HOME_PATH}) + set(R_FRAMEWORK_PATH "${CMAKE_BINARY_DIR}/Frameworks") + set(R_HOME_PATH "${R_FRAMEWORK_PATH}/R.framework/Versions/${R_DIR_NAME}/Resources") + set(R_LIBRARY_PATH "${R_HOME_PATH}/library") + set(R_OPT_PATH "${R_HOME_PATH}/opt") + set(R_EXECUTABLE "${R_HOME_PATH}/bin/R") + set(R_INCLUDE_PATH "${R_HOME_PATH}/include") + set(RCPP_PATH "${R_LIBRARY_PATH}/Rcpp") + set(RINSIDE_PATH "${R_LIBRARY_PATH}/RInside") + set(RENV_PATH "${R_LIBRARY_PATH}/renv") + set(ENV{JASP_R_HOME} ${R_HOME_PATH}) + #set(ENV{R_HOME} ${R_HOME_PATH}) #enabling this breaks the output from R because it will add a warning about: `WARNING: ignoring environment value of R_HOME` cmake_print_variables(R_FRAMEWORK_PATH) cmake_print_variables(R_HOME_PATH) @@ -495,7 +494,7 @@ if(APPLE) message(CHECK_START "Patching /bin/exec/R") execute_process( #COMMAND_ECHO STDOUT - #ERROR_QUIET + #ERROR_QUIET OUTPUT_QUIET WORKING_DIRECTORY ${R_HOME_PATH} COMMAND @@ -511,14 +510,14 @@ if(APPLE) set(SIGNING_RESULT "timeout") while((${SIGNING_RESULT} MATCHES "timeout") OR (${SIGNING_RESULT} STREQUAL "1")) execute_process( - COMMAND_ECHO STDOUT + #COMMAND_ECHO STDOUT #ERROR_QUIET - #OUTPUT_QUIET + OUTPUT_QUIET TIMEOUT 30 WORKING_DIRECTORY ${R_HOME_PATH} COMMAND codesign --force --verbose --deep ${CODESIGN_TIMESTAMP_FLAG} --sign - ${APPLE_CODESIGN_IDENTITY} ${OPTIONS_RUNTIME} + ${APPLE_CODESIGN_IDENTITY} ${OPTIONS_RUNTIME} "${R_HOME_PATH}/bin/exec/R" RESULT_VARIABLE SIGNING_RESULT OUTPUT_VARIABLE SIGNING_OUTPUT @@ -546,6 +545,23 @@ if(APPLE) endif() + message(CHECK_START "Locating the 'gfortran'") + + find_program( + FORTRAN_EXECUTABLE + NAMES gfortran + PATHS ${GFORTRAN_PATH} + NO_DEFAULT_PATH + DOC "'gfortran' is needed for building some of the R packages") + + if(NOT FORTRAN_EXECUTABLE) + message(CHECK_FAIL "not found") + message(FATAL_ERROR "Please install 'gfortran' before continuing.") + else() + message(CHECK_PASS "found") + message(STATUS "FORTRAN_EXECUTABLE=${FORTRAN_EXECUTABLE}") + endif() + endif() # @@ -601,109 +617,15 @@ if(APPLE) message(CHECK_FAIL "not found in ${R_HOME_PATH}/lib") endif() - if(NOT EXISTS ${RINSIDE_PATH}) - message(STATUS "RInside is not installed!") - - message(CHECK_START "Installing the 'RInside' and 'Rcpp'") - - configure_file(${MODULES_SOURCE_PATH}/install-RInside.R.in - ${SCRIPT_DIRECTORY}/install-RInside.R @ONLY) - - execute_process( - COMMAND_ECHO STDOUT - #ERROR_QUIET OUTPUT_QUIET - WORKING_DIRECTORY ${R_HOME_PATH} - COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save - --file=${SCRIPT_DIRECTORY}/install-RInside.R) - - if(NOT EXISTS ${R_LIBRARY_PATH}/RInside) - message(CHECK_FAIL "unsuccessful.") - message(FATAL_ERROR "'RInside' installation has failed!") - endif() - - message(CHECK_PASS "successful.") - - # Patching RInside and RCpp - message(CHECK_START "Patching Frameworks/.../library") - execute_process( - #COMMAND_ECHO STDOUT - #ERROR_QUIET - OUTPUT_QUIET - WORKING_DIRECTORY ${R_HOME_PATH} - COMMAND - ${CMAKE_COMMAND} -D - NAME_TOOL_PREFIX_PATCHER=${PROJECT_SOURCE_DIR}/Tools/macOS/install_name_prefix_tool.sh - -D PATH=${R_HOME_PATH}/library -D R_HOME_PATH=${R_HOME_PATH} - -D R_DIR_NAME=${R_DIR_NAME} -D SIGNING_IDENTITY=${APPLE_CODESIGN_IDENTITY} - -D SIGNING=1 -D CODESIGN_TIMESTAMP_FLAG=${CODESIGN_TIMESTAMP_FLAG} -P - ${PROJECT_SOURCE_DIR}/Tools/CMake/Patch.cmake) - - endif() - - if(NOT EXISTS ${RENV_PATH}) - message(STATUS "renv is not installed!") - message(CHECK_START "Installing 'renv'") - - configure_file(${MODULES_SOURCE_PATH}/install-renv.R.in - ${SCRIPT_DIRECTORY}/install-renv.R @ONLY) - - set(ENV{JASP_R_HOME} ${R_HOME_PATH}) - - execute_process( - COMMAND_ECHO STDERR - #ERROR_QUIET OUTPUT_QUIET - WORKING_DIRECTORY ${R_HOME_PATH} - COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save --file=${SCRIPT_DIRECTORY}/install-renv.R) - - if(NOT EXISTS ${R_LIBRARY_PATH}/renv) - message(CHECK_FAIL "unsuccessful.") - message(FATAL_ERROR "'renv' installation has failed!") - endif() - - message(CHECK_PASS "successful.") - - message(CHECK_START "Patching Frameworks/.../library") - execute_process( - #COMMAND_ECHO STDOUT - #ERROR_QUIET - OUTPUT_QUIET - WORKING_DIRECTORY ${R_HOME_PATH} - COMMAND - ${CMAKE_COMMAND} -D - NAME_TOOL_PREFIX_PATCHER=${PROJECT_SOURCE_DIR}/Tools/macOS/install_name_prefix_tool.sh - -D PATH=${R_HOME_PATH}/library -D R_HOME_PATH=${R_HOME_PATH} - -D R_DIR_NAME=${R_DIR_NAME} -D SIGNING_IDENTITY=${APPLE_CODESIGN_IDENTITY} - -D SIGNING=1 -D CODESIGN_TIMESTAMP_FLAG=${CODESIGN_TIMESTAMP_FLAG} -P - ${PROJECT_SOURCE_DIR}/Tools/CMake/Patch.cmake) - endif() - - message(CHECK_START "Checking for 'libRInside'") - find_library( - _LIB_RINSIDE - NAMES RInside - PATHS ${RINSIDE_PATH}/lib - NO_DEFAULT_PATH NO_CACHE REQUIRED) - - if(_LIB_RINSIDE) - message(CHECK_PASS "found.") - message(STATUS " ${_LIB_RINSIDE}") - else() - message(CHECK_FAIL "not found in ${RINSIDE_PATH}/lib") - endif() - elseif(WIN32) - set(R_HOME_PATH "${CMAKE_BINARY_DIR}/R") - set(R_BIN_PATH "${R_HOME_PATH}/bin") - set(R_LIB_PATH "${R_HOME_PATH}/bin/${R_DIR_NAME}") - set(R_LIBRARY_PATH "${R_HOME_PATH}/library") - set(R_OPT_PATH "${R_HOME_PATH}/opt") - set(R_EXECUTABLE "${R_HOME_PATH}/bin/R") - set(R_INCLUDE_PATH "${R_HOME_PATH}/include") - set(RCPP_PATH "${R_LIBRARY_PATH}/Rcpp") - set(RINSIDE_PATH "${R_LIBRARY_PATH}/RInside") - set(RENV_PATH "${R_LIBRARY_PATH}/renv") - + set(R_HOME_PATH "${CMAKE_BINARY_DIR}/R") + set(R_BIN_PATH "${R_HOME_PATH}/bin") + set(R_LIB_PATH "${R_HOME_PATH}/bin/${R_DIR_NAME}") + set(R_LIBRARY_PATH "${R_HOME_PATH}/library") + set(R_OPT_PATH "${R_HOME_PATH}/opt") + set(R_EXECUTABLE "${R_HOME_PATH}/bin/R") + set(R_INCLUDE_PATH "${R_HOME_PATH}/include") # This will be added to the install.packages calls set(USE_LOCAL_R_LIBS_PATH ", lib='${R_LIBRARY_PATH}'") @@ -714,10 +636,6 @@ elseif(WIN32) cmake_print_variables(R_OPT_PATH) cmake_print_variables(R_EXECUTABLE) - cmake_print_variables(RCPP_PATH) - cmake_print_variables(RINSIDE_PATH) - cmake_print_variables(RENV_PATH) - message(CHECK_START "Checking for R/") if(NOT EXISTS ${CMAKE_BINARY_DIR}/R) @@ -788,52 +706,6 @@ elseif(WIN32) endif() - if(NOT EXISTS ${RENV_PATH}) - message(STATUS "renv is not installed!") - message(CHECK_START "Installing 'renv'") - - configure_file(${MODULES_SOURCE_PATH}/install-renv.R.in - ${SCRIPT_DIRECTORY}/install-renv.R @ONLY) - - execute_process( - COMMAND_ECHO STDOUT - #ERROR_QUIET OUTPUT_QUIET - WORKING_DIRECTORY ${R_HOME_PATH} - COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save - --file=${SCRIPT_DIRECTORY}/install-renv.R) - - if(NOT EXISTS ${R_LIBRARY_PATH}/renv) - message(CHECK_FAIL "unsuccessful.") - message(FATAL_ERROR "'renv' installation has failed!") - endif() - - message(CHECK_PASS "successful.") - endif() - - if(NOT EXISTS ${RINSIDE_PATH}) - message(STATUS "RInside is not installed!") - - message(CHECK_START "Installing the 'RInside' and 'Rcpp'") - - configure_file(${MODULES_SOURCE_PATH}/install-RInside.R.in - ${SCRIPT_DIRECTORY}/install-RInside.R @ONLY) - - execute_process( - COMMAND_ECHO STDOUT - #ERROR_QUIET OUTPUT_QUIET - WORKING_DIRECTORY ${R_BIN_PATH} - COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save - --file=${SCRIPT_DIRECTORY}/install-RInside.R) - - if(NOT EXISTS ${R_LIBRARY_PATH}/RInside) - message(CHECK_FAIL "unsuccessful.") - message(FATAL_ERROR "'RInside' installation has failed!") - endif() - - message(CHECK_PASS "successful.") - - endif() - elseif(LINUX) message(CHECK_START "Looking for R") @@ -901,16 +773,12 @@ elseif(LINUX) endif() set(R_EXECUTABLE "${R_HOME_PATH}/bin/R") - set(RSCRIPT_EXECUTABLE "${R_HOME_PATH}/bin/Rscript") - set(RCPP_PATH "${R_LIBRARY_PATH}/Rcpp") - set(RINSIDE_PATH "${R_LIBRARY_PATH}/RInside") - set(RENV_PATH "${R_LIBRARY_PATH}/renv") set(USE_LOCAL_R_LIBS_PATH ", lib='${R_LIBRARY_PATH}'") message(CHECK_START "Looking for R.h") # ask R where it thinks it's include folder is - execute_process(COMMAND ${RSCRIPT_EXECUTABLE} -e "cat(R.home(\"include\"))" OUTPUT_VARIABLE R_INCLUDE_PATH) + execute_process(COMMAND command -E env "JASP_R_HOME=${R_HOME_PATH}" ${R_EXECUTABLE} --slave --no-restore --no-save -e "cat(R.home(\"include\"))" OUTPUT_VARIABLE R_INCLUDE_PATH) # if R returns a nonexisting directory, try some fallback locations if(NOT EXISTS ${R_INCLUDE_PATH}) message(STATUS "R return an invalid include directory, trying fallbacks") @@ -953,50 +821,71 @@ elseif(LINUX) message(CHECK_FAIL "not found in ${R_HOME_PATH}/lib") endif() - if(NOT EXISTS ${RENV_PATH}) - message(STATUS "renv is not installed!") - message(CHECK_START "Installing 'renv'") +endif() - configure_file(${MODULES_SOURCE_PATH}/install-renv.R.in - ${SCRIPT_DIRECTORY}/install-renv.R @ONLY) +set(RENV_LIBRARY "${CMAKE_BINARY_DIR}/_cache/R/renv_library") +set(R_CPP_INCLUDES_LIBRARY "${CMAKE_BINARY_DIR}/Modules/Tools/R_cpp_includes_library") +set(JASPMODULEINSTALLER_LIBRARY "${CMAKE_BINARY_DIR}/Modules/Tools/jaspModuleInstaller_library") +set(PKGDEPENDS_LIBRARY "${CMAKE_BINARY_DIR}/Modules/Tools/pkgdepends_library") +set(JUNCTION_HANDLING_LIBRARY "${CMAKE_BINARY_DIR}/Modules/Tools/junction_bootstrap_library") - execute_process( - COMMAND_ECHO STDOUT - #ERROR_QUIET OUTPUT_QUIET - WORKING_DIRECTORY ${R_HOME_PATH} - COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save - --file=${SCRIPT_DIRECTORY}/install-renv.R) +SET(RENV_SANDBOX "${CMAKE_BINARY_DIR}/_cache/R/renv_sandbox") +file(MAKE_DIRECTORY ${RENV_SANDBOX}) +# TODO: it could be nice to ship the sandbox so it can be used to install dynamic modules +# also, the sandbox paths may need to be adjusted on windows (they are symlinks) - if(NOT EXISTS ${R_LIBRARY_PATH}/renv) - message(CHECK_FAIL "unsuccessful.") - message(FATAL_ERROR "'renv' installation has failed!") - endif() +message(STATUS "Setting up renv, Rcpp, RInside, and jaspModuleInstaller") +message(STATUS "RENV_LIBRARY = ${RENV_LIBRARY}") +message(STATUS "R_CPP_INCLUDES_LIBRARY = ${R_CPP_INCLUDES_LIBRARY}") - message(CHECK_PASS "successful.") - endif() +configure_file(${PROJECT_SOURCE_DIR}/Modules/setup_renv_rcpp_rinside.R.in + ${SCRIPT_DIRECTORY}/setup_renv_rcpp_rinside.R @ONLY) - if(NOT EXISTS ${RINSIDE_PATH}) - message(STATUS "RInside is not installed!") +execute_process( + COMMAND_ECHO STDOUT + #ERROR_QUIET OUTPUT_QUIET + WORKING_DIRECTORY ${R_HOME_PATH} + COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save --file=${SCRIPT_DIRECTORY}/setup_renv_rcpp_rinside.R) - message(CHECK_START "Installing the 'RInside' and 'Rcpp'") +if(APPLE) + # Patch RInside and RCpp + message(CHECK_START "Patching ${R_CPP_INCLUDES_LIBRARY}") + execute_process( + COMMAND_ECHO STDOUT + #ERROR_QUIET OUTPUT_QUIET + WORKING_DIRECTORY ${R_HOME_PATH} + COMMAND + ${CMAKE_COMMAND} -D + NAME_TOOL_PREFIX_PATCHER=${PROJECT_SOURCE_DIR}/Tools/macOS/install_name_prefix_tool.sh + -D PATH=${R_CPP_INCLUDES_LIBRARY} -D R_HOME_PATH=${R_HOME_PATH} -D + R_DIR_NAME=${R_DIR_NAME} -D SIGNING_IDENTITY=${APPLE_CODESIGN_IDENTITY} + -D SIGNING=1 -D CODESIGN_TIMESTAMP_FLAG=${CODESIGN_TIMESTAMP_FLAG} -P + ${PROJECT_SOURCE_DIR}/Tools/CMake/Patch.cmake + ) +endif() - configure_file(${MODULES_SOURCE_PATH}/install-RInside.R.in - ${SCRIPT_DIRECTORY}/install-RInside.R @ONLY) +include(FindRPackagePath) - execute_process( - COMMAND_ECHO STDOUT - COMMAND ${R_EXECUTABLE} --slave --no-restore --no-save - --file=${SCRIPT_DIRECTORY}/install-RInside.R) +find_package_path(RCPP_PATH ${R_CPP_INCLUDES_LIBRARY} "Rcpp") +find_package_path(RINSIDE_PATH ${R_CPP_INCLUDES_LIBRARY} "RInside") - if(NOT EXISTS ${R_LIBRARY_PATH}/RInside) - message(CHECK_FAIL "unsuccessful.") - message(FATAL_ERROR "'RInside' installation has failed!") - endif() +set(RENV_PATH "${RENV_LIBRARY}/renv") - message(CHECK_PASS "successful.") +message(STATUS "RENV_PATH = ${RENV_PATH}") +message(STATUS "RCPP_PATH = ${RCPP_PATH}") +message(STATUS "RINSIDE_PATH = ${RINSIDE_PATH}") - endif() +# if(NOT EXISTS ${RENV_PATH}) +# message(FATAL_ERROR "'renv' installation has failed!") +# endif() +if(NOT EXISTS ${RCPP_PATH}) + message(FATAL_ERROR "'Rcpp' installation has failed!") +endif() +if(NOT EXISTS ${RINSIDE_PATH}) + message(FATAL_ERROR "'RInside' installation has failed!") +endif() +if(APPLE OR LINUX) message(CHECK_START "Checking for 'libRInside'") find_library( _LIB_RINSIDE @@ -1010,7 +899,6 @@ elseif(LINUX) else() message(CHECK_FAIL "not found in ${RINSIDE_PATH}/lib") endif() - endif() list(POP_BACK CMAKE_MESSAGE_CONTEXT) diff --git a/Tools/checkPOFiles.sh b/Tools/checkPOFiles.sh new file mode 100644 index 0000000000..1d24d546e0 --- /dev/null +++ b/Tools/checkPOFiles.sh @@ -0,0 +1,17 @@ +function checkPO { + for LANGUAGE in cs de eo es eu fr gl id ja nl pl pt_BR pt ru zh_Hans zh_Hant + do + PO_FILE="po/QML-${LANGUAGE}.po" + if [ -e ${PO_FILE} ] + then + if ! grep X-Language ${PO_FILE} >> /dev/null 2>&1 + then + echo "No X-Language for ${LANGUAGE}" + fi + fi + done +} + +export -f checkPO + +git submodule foreach checkPO diff --git a/Tools/find_package_path.R b/Tools/find_package_path.R new file mode 100755 index 0000000000..4dbe38a3d6 --- /dev/null +++ b/Tools/find_package_path.R @@ -0,0 +1,29 @@ +args <- commandArgs() +#print(args) + +pkgName <- args[[ length(args) ]] +pkgLib <- args[[ length(args) - 1 ]] +#print(pkgName) +#print(pkgLib) +# usage + +# R --file=renv_new_idea_find_package_path.R --args library packagename [subdir 1] [subdir 2] ... + +# throws if the package or directory does not exist. + + +# R-4.3.1 --file=renv_new_idea_find_package_path.R --args /home/don/R/x86_64-pc-linux-gnu-library/4.2 Rcpp +# R-4.3.1 --file=renv_new_idea_find_package_path.R --args /home/don/R/x86_64-pc-linux-gnu-library/4.2 Rcpp include +# args <- c( +# "/home/don/R/x86_64-pc-linux-gnu-library/4.2", +# "Rcpp" +# ) +result <- find.package(package = pkgName, lib.loc = pkgLib) + +#if (length(args) > 2L) +# result <- do.call(file.path, c(result, as.list(args[3:length(args)]))) + +if (!(dir.exists(result) || file.exists(result))) + stop("target file/ directory does not exist!") + +cat(normalizePath(result)) diff --git a/Tools/flatpak/JASP-screenshot-0.png b/Tools/flatpak/JASP-screenshot-0.png deleted file mode 100644 index d5a7e7d0f1..0000000000 Binary files a/Tools/flatpak/JASP-screenshot-0.png and /dev/null differ diff --git a/Tools/flatpak/RPackages.json b/Tools/flatpak/RPackages.json deleted file mode 100644 index db73b7fb3f..0000000000 --- a/Tools/flatpak/RPackages.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "RPackages2", - "buildsystem": "simple", - "build-commands": [], - "modules": - [ - { - "name": "Rpackages", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/flatpak_archive.tar.gz", - "sha256": "63400dc87d1e3fa0179cb01a18e75b67b2de46d598e6a51e83f3b4a35b200118" - } - ], - "build-commands": [ "R --vanilla --file=flatpak-helper/r-helpers/flatpakRegenerateRenvStructure.R" ] - } - ] -} - diff --git a/Tools/flatpak/cleanFlatpak.sh b/Tools/flatpak/cleanFlatpak.sh new file mode 100755 index 0000000000..0479a38022 --- /dev/null +++ b/Tools/flatpak/cleanFlatpak.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +echo "Cleaning up flatpak" +pwd +#Cant use the cellar post build. +rm -rf /app/lib64/cellar/ +#cant delete read only renv cache stuff. very annoying +chmod -R +w _cache/ +rm -rf _cache diff --git a/Tools/flatpak/collectCellar.sh b/Tools/flatpak/collectCellar.sh new file mode 100755 index 0000000000..9d9a8e9440 --- /dev/null +++ b/Tools/flatpak/collectCellar.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +rm -rf ./_tmpCellar ./cellar.tar.gz +mkdir -p _tmpCellar/cellar +find $1/_cache/renv-root/source/ | grep -E "*.tar.gz" | xargs -i cp {} ./_tmpCellar/cellar +tar -C _tmpCellar -czf ./cellar.tar.gz cellar +rm -rf ./_tmpCellar diff --git a/Tools/flatpak/expectedPackages.json b/Tools/flatpak/expectedPackages.json deleted file mode 100644 index a64f73a3fc..0000000000 --- a/Tools/flatpak/expectedPackages.json +++ /dev/null @@ -1,3640 +0,0 @@ - { - "name": "abind", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/abind_1.4-5.tar.gz", - "sha256": "3a3ace5afbcb86e56889efcebf3bf5c3bb042a282ba7cc4412d450bb246a3f2c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "acepack", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/acepack_1.4.1.tar.gz", - "sha256": "82750507926f02a696f6cc03693e8d4a5ee7e92500c8c15a16a9c12addcd28b9" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "assertthat", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/assertthat_0.2.0.tar.gz", - "sha256": "d73ef79b1e75293ed889a99571b237a95829c099f7da094d4763f83ea6fde5f2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "backports", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/backports_1.1.3.tar.gz", - "sha256": "e41bd146824ec921994f1b176d0e4cca0b36dd3db32ca7a954d872a5ba214cc1" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "Bain", - "buildsystem": "simple", - "sources": [ - { - "type": "git", - "url": "https://github.com/jasp-stats/BAIN-for-JASP", - "commit": "1b03f71204839da29a4219e8bba99b8ec8479612" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "BAS", - "buildsystem": "simple", - "sources": [ - { - "type": "git", - "url": "https://github.com/vandenman/BAS", - "commit": "abb73a6ac9d145ced3586434d413130b2f6263e9" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "base64enc", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/base64enc_0.1-3.tar.gz", - "sha256": "6d856d8a364bcdc499a0bf38bfd283b7c743d08f0b288174fba7dbf0a04b688d" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "BH", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/BH_1.69.0-1.tar.gz", - "sha256": "a0fd4364b7e368f09c56dec030823f52c16da0787580af7e4615eddeb99baca2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "BMS", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/BMS_0.3.4.tar.gz", - "sha256": "14f340f038fc8eadec694457f896c89a4b02ec845aad360172f0bad07a98757c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "brew", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/brew_1.0-6.tar.gz", - "sha256": "d70d1a9a01cf4a923b4f11e4374ffd887ad3ff964f35c6f9dc0f29c8d657f0ed" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ca", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ca_0.71.tar.gz", - "sha256": "021e653b373d311818a8a6d0f78c27bf03448df3097452a33f5a279681dc98fb" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "carData", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/carData_3.0-2.tar.gz", - "sha256": "3b5c4eff1cc1e456a5331084774503eaa06cf61fb7acf6b9e8a6bfabd5735494" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "checkmate", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/checkmate_1.9.1.tar.gz", - "sha256": "b71c368b8ac14c0568a366e4a8a0996cb411485a3da7cefe75fece52eca79ef8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "clipr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/clipr_0.5.0.tar.gz", - "sha256": "fd303f8b7f29badcdf490bb2d579acdfc4f4e1aa9c90ac77ab9d05ce3d053dbf" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "clisymbols", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/clisymbols_1.2.0.tar.gz", - "sha256": "0649f2ce39541820daee3ed408d765eddf83db5db639b493561f4e5fbf88efe0" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "cmprsk", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/cmprsk_2.2-7.tar.gz", - "sha256": "952da4a0fd55a039f64f619c2c7cc29ba2490985ca67d2853de511692f1fb9c6" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "cocor", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/cocor_1.1-3.tar.gz", - "sha256": "22503ef02f450e2c60056d286603faa3ac0789fc45ed0b9e9788c6eb73f6df80" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "coda", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/coda_0.19-2.tar.gz", - "sha256": "678a7e6a87a2723089daeb780ea37ac3d4319b37eabe26928ea3fa9c9b1eda0d" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "colorspace", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/colorspace_1.4-0.tar.gz", - "sha256": "ce003c5958dd704697959e9dc8a108c8cb568f8d78ece113235732afc5dff556" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "commonmark", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/commonmark_1.7.tar.gz", - "sha256": "d14a767a3ea9778d6165f44f980dd257423ca6043926e3cd8f664f7171f89108" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "contfrac", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/contfrac_1.1-12.tar.gz", - "sha256": "95bfc5e970513416c080486a1cd8dfd9f8d59fb691b02ef6ccbe0ce1ed61056b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "corpcor", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/corpcor_1.6.9.tar.gz", - "sha256": "2e4fabd1d3936fecea67fa365233590147ca50bb45cf80efb53a10345a8a23c2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "corrplot", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/corrplot_0.84.tar.gz", - "sha256": "0dce5e628ead9045580a191f60c58fd7c75b4bbfaaa3307678fc9ed550c303cc" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "crayon", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/crayon_1.3.4.tar.gz", - "sha256": "fc6e9bf990e9532c4fcf1a3d2ce22d8cf12d25a95e4779adfa17713ed836fa68" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "curl", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/curl_3.3.tar.gz", - "sha256": "0cb0b9a9280edc42ebed94708541ec86b4f48779e722171e45227eab8a88a5bd" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "data.table", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/data.table_1.12.0.tar.gz", - "sha256": "611b112123dbd4ebd5200770fcdfaaeaab622adeb2b290d36018d3092742e3f7" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "DBI", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/DBI_1.0.0.tar.gz", - "sha256": "ff16f118eb3f759183441835e932b87358dd80ab9800ce576a8f3df1b6f01cf5" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "deSolve", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/deSolve_1.21.tar.gz", - "sha256": "45c372d458fe4c7c11943d4c409517849b1be6782dc05bd9a74b066e67250c63" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "digest", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/digest_0.6.18.tar.gz", - "sha256": "726de348dc41140cdc3c0111590e4824b03536ce36bf0ad93f1c798e32d8714c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "e1071", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/e1071_1.7-0.1.tar.gz", - "sha256": "097b184f9f651785ade28da3ec0e7fb1aa71ed747f73f6d5a44acf0a35a9d885" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "eigenmodel", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/eigenmodel_1.10.tar.gz", - "sha256": "4adf7da3df42e9bf2e1359aa2e802da76dc59d3f0f99b588f405eb8b6f1cc1f4" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ellipse", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ellipse_0.4.1.tar.gz", - "sha256": "1a9a9c52195b26c2b4d51ad159ab98aff7aa8ca25fdc6b2198818d1a0adb023d" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "elliptic", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/elliptic_1.3-9.tar.gz", - "sha256": "81db271d891afbe13b4cc44a67573ddfef6df9ce7c10f87895fdd074219d813f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "estimability", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/estimability_1.3.tar.gz", - "sha256": "a33179c5fbd6a1a623d90cb6f1743148f92c09429fac466867f3ea70946a2e32" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "evaluate", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/evaluate_0.13.tar.gz", - "sha256": "58dc412d38696ffca040adf860bb733981d24abc96eab424d7ac639d8f60fb45" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "fansi", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/fansi_0.4.0.tar.gz", - "sha256": "e104e9d01c7ff8a847f6b332ef544c0ef912859f9c6a514fe2e6f3b34fcfc209" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "fdrtool", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/fdrtool_1.2.15.tar.gz", - "sha256": "65f964aa768d0703ceb7a199adc5e79ca79a6d29d7bc053a262eb533697686c0" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "Formula", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/Formula_1.2-3.tar.gz", - "sha256": "1411349b20bd09611a9fd0ee6d15f780c758ad2b0e490e908facb49433823872" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "generics", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/generics_0.0.2.tar.gz", - "sha256": "71b3d1b719ce89e71dd396ac8bc6aa5f1cd99bbbf03faff61dfbbee32fec6176" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "git2r", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/git2r_0.24.0.tar.gz", - "sha256": "ef813f28dcef76109e7fdc24ac00db539c253f977f5ccb12617714497e11cc6d" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "glasso", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/glasso_1.10.tar.gz", - "sha256": "e6fa74139a2b5f475f134cc0d6b4000ed870beb5865294e9f1d68b4d42bf505b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "glue", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/glue_1.3.0.tar.gz", - "sha256": "789e5a44c3635c3d3db26666e635e88adcf61cd02b75465125d95d7a12291cee" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "GPArotation", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/GPArotation_2014.11-1.tar.gz", - "sha256": "351bc15fc8dc6c8ea5045fbba22180d1e68314fc34d267545687748e312e5096" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "gtable", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/gtable_0.2.0.tar.gz", - "sha256": "801e4869830ff3da1d38e41f5a2296a54fc10a7419c6ffb108582850c701e76f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "gtools", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/gtools_3.8.1.tar.gz", - "sha256": "051484459bd8ad1b03425b8843d24f6828fea18f7357cfa1c192198cc3f4ba38" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "highr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/highr_0.7.tar.gz", - "sha256": "cabba5b6f2ea82024a49c5ced5f1aa476f864bc52bc129038e319e4e26b6f3b7" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "hmeasure", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/hmeasure_1.0-2.tar.gz", - "sha256": "1c56689e76a72bbef60dab92b23e87908793ce68afdaa0546c6d8a51bca59650" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "hypergeo", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/hypergeo_1.2-13.tar.gz", - "sha256": "6d5b78353aad1d13091ccbeb340867dad7b9eb00d0e2185286dc7e13848f4d8e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ini", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ini_0.3.1.tar.gz", - "sha256": "7b191a54019c8c52d6c2211c14878c95564154ec4865f57007953742868cd813" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "iterators", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/iterators_1.0.10.tar.gz", - "sha256": "a9e1b2302828d4527766ce12fa9ae06faf8d51e819a43f8efef632b6ddf471e8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "jpeg", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/jpeg_0.1-8.tar.gz", - "sha256": "d032befeb3a414cefdbf70ba29a6c01541c54387cc0a1a98a4022d86cbe60a16" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "jsonlite", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/jsonlite_1.6.tar.gz", - "sha256": "88c5b425229966b7409145a6cabc72db9ed04f8c37ee95901af0146bb285db53" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "labeling", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/labeling_0.3.tar.gz", - "sha256": "0d8069eb48e91f6f6d6a9148f4e2dc5026cabead15dd15fc343eff9cf33f538f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "lazyeval", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/lazyeval_0.2.1.tar.gz", - "sha256": "83b3a43e94c40fe7977e43eb607be0a3cd64c02800eae4f2774e7866d1e93f61" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "lisrelToR", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/lisrelToR_0.1.4.tar.gz", - "sha256": "e58ecdb5c8fcf91dd1679750aabdd946973d9c5dfeaa7083553d42383ec02c7e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "logspline", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/logspline_2.1.12.tar.gz", - "sha256": "53d2d3b151e8d99e651c4acbea13be51370be9310ac9160988e030c8c21698f8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "longitudinal", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/longitudinal_1.1.12.tar.gz", - "sha256": "d4f894c38373ba105b1bdc89e3e7c1b215838e2fb6b4470b9f23768b84e603b5" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "lsei", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/lsei_1.2-0.tar.gz", - "sha256": "4781ebd9ef93880260d5d5f23066580ac06061e95c1048fb25e4e838963380f6" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "magrittr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/magrittr_1.5.tar.gz", - "sha256": "05c45943ada9443134caa0ab24db4a962b629f00b755ccf039a2a2a7b2c92ae8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "matrixcalc", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/matrixcalc_1.0-3.tar.gz", - "sha256": "17e6caeeecd596b850a6caaa257984398de9ec5d2b41ce83c428f112614b9cb0" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "MatrixModels", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/MatrixModels_0.4-1.tar.gz", - "sha256": "fe878e401e697992a480cd146421c3a10fa331f6b37a51bac83b5c1119dcce33" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "matrixStats", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/matrixStats_0.54.0.tar.gz", - "sha256": "8f0db4e181300a208b9aedbebfdf522a2626e6675d2662656efb8ba71b05a06f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "mdscore", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/mdscore_0.1-3.tar.gz", - "sha256": "12f5841258f7d9bdc8074244bfb76482df0e480f09835d666c90a5364d2e9481" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "memoise", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/memoise_1.1.0.tar.gz", - "sha256": "b276f9452a26aeb79e12dd7227fcc8712832781a42f92d70e86040da0573980c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "metafor", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/metafor_2.0-0.tar.gz", - "sha256": "26fd80b631244b5cae37325b92ede59208f9da93c28193cb05a4850c4fe32440" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "mime", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/mime_0.6.tar.gz", - "sha256": "4775b605ab0117406bee7953c8af59eea8b35e67d1bd63f4007686a7097fc401" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "mitools", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/mitools_2.3.tar.gz", - "sha256": "63282951aa9e24564693d636c59a4dee29380e99004269493bedb98a28fbe670" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "mnormt", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/mnormt_1.5-5.tar.gz", - "sha256": "ff78d5f935278935f1814a69e5a913d93d6dd2ac1b5681ba86b30c6773ef64ac" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "modules", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/modules_0.8.0.tar.gz", - "sha256": "13cd5090328891a02bccfe90b1cd8d093305ff2de63d82392630a949a8b5f4f7" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "moments", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/moments_0.14.tar.gz", - "sha256": "2a3b81e60dafdd092d2bdd3513d7038855ca7d113dc71df1229f7518382a3e39" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "munsell", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/munsell_0.5.0.tar.gz", - "sha256": "d0f3a9fb30e2b5d411fa61db56d4be5733a2621c0edf017d090bdfa5e377e199" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "mvtnorm", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/mvtnorm_1.0-8.tar.gz", - "sha256": "2010cab50fb7a5117e3c61f06e4a797ea6bf92b1ab20c132cb929d453d154451" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "nloptr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/nloptr_1.2.1.tar.gz", - "sha256": "1f86e33ecde6c3b0d2098c47591a9cd0fa41fb973ebf5145859677492730df97" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "nnls", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/nnls_1.4.tar.gz", - "sha256": "0e5d77abae12bc50639d34354f96a8e079408c9d7138a360743b73bd7bce6c1f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "nortest", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/nortest_1.0-4.tar.gz", - "sha256": "a3850a048181d5d059c1e74903437569873b430c915b709808237d71fee5209f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "npsurv", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/npsurv_0.4-0.tar.gz", - "sha256": "404cf7135dc40a04e9b81224a543307057a8278e11109ba1fcaa28e87c6204f3" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "numDeriv", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/numDeriv_2016.8-1.tar.gz", - "sha256": "1b681d273697dc780a3ac5bedabb4a257785732d9ca4ef68e4e4aac8b328d11e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "pan", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/pan_1.6.tar.gz", - "sha256": "adc0df816ae38bc188bce0aef3aeb71d19c0fc26e063107eeee71a81a49463b6" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "pbapply", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/pbapply_1.4-0.tar.gz", - "sha256": "f3741b625e0687f6ef80ffabd767c912cdd0def033d16c992abe9b116d52c72e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "pbivnorm", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/pbivnorm_0.6.0.tar.gz", - "sha256": "07c37d507cb8f8d2d9ae51a9a6d44dfbebd8a53e93c242c4378eaddfb1cc5f16" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "pkgconfig", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/pkgconfig_2.0.2.tar.gz", - "sha256": "25997754d1adbe7a251e3bf9879bb52dced27dd8b84767d558f0f644ca8d69ca" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "plogr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/plogr_0.2.0.tar.gz", - "sha256": "0e63ba2e1f624005fe25c67cdd403636a912e063d682eca07f2f1d65e9870d29" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "plotrix", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/plotrix_3.7-4.tar.gz", - "sha256": "d246c93666629a8ee7e62c5dfb91f5f6efe5a4f6dbc61c5f2a850c8d15ff40c3" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "png", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/png_0.1-7.tar.gz", - "sha256": "e269ff968f04384fc9421d17cfc7c10cf7756b11c2d6d126e9776f5aca65553c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "polynom", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/polynom_1.3-9.tar.gz", - "sha256": "d35a50925cc5552a6aac0816a91dbc03e9fd77da47e06d27572fde9dcbee9de8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ppcor", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ppcor_1.1.tar.gz", - "sha256": "6a78f0c4d9caa17ab0252c5d351c2371e4ffb9047ebd13964877018dd6142bf5" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ppls", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ppls_1.6-1.1.tar.gz", - "sha256": "bda283ddd72920ca9011b8718f6ea28d9fe2743050ae204d429f1136bc8ed9ff" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "praise", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/praise_1.0.0.tar.gz", - "sha256": "5c035e74fd05dfa59b03afe0d5f4c53fbf34144e175e90c53d09c6baedf5debd" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "prettyunits", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/prettyunits_1.0.2.tar.gz", - "sha256": "35a4980586c20650538ae1e4fed4d80fdde3f212b98546fc3c7d9469a1207f5c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ps", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ps_1.3.0.tar.gz", - "sha256": "289193d0ccd2db0b6fe8702e8c5711e935219b17f90f01a6e9684982413e98d1" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "psych", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/psych_1.8.12.tar.gz", - "sha256": "6e175e049bc1ee5b79a9e51ccafb22b962b4e6c839ce5c9cfa1ad83967037743" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "psychTools", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/psychTools_1.9.5.26.tar.gz", - "sha256": "c23a76495a8df4d90033eaddb09fb67fe27ad7978fd8e9761582564b1f3acfa8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "pwr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/pwr_1.2-2.tar.gz", - "sha256": "550f021c2ff675ebdcd08116d01ea2073164f289f541ffc7dde7984c033aaf64" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "quadprog", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/quadprog_1.5-5.tar.gz", - "sha256": "d999620688354c283de5bb305203f5db70271b4dfdc23577cae8c2ba94c9e349" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "qvcalc", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/qvcalc_0.9-1.tar.gz", - "sha256": "de2311ade76dae311b2b5632633003667aa46cdb8703a330b84b67c4b90f87d2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "R.methodsS3", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/R.methodsS3_1.7.1.tar.gz", - "sha256": "44b840399266cd27f8f9157777b4d9d85ab7bd31bfdc143b3fc45079a2d8e687" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "R.oo", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/R.oo_1.22.0.tar.gz", - "sha256": "c0862e4608fb2b8f91ec4494d46c2f3ba7bc44999f9aa3d7b9625d3792e7dd4c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "R.utils", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/R.utils_2.8.0.tar.gz", - "sha256": "cfc54dd2a7fd7f8d840f2d58615fdba1cccc3ecde325385180ff3e191acd4ac9" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "R6", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/R6_2.4.0.tar.gz", - "sha256": "70be110174fbf5f5304049b186a6f9c05b77bfaec6d8caf980fcef5da6e0abce" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "RColorBrewer", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/RColorBrewer_1.1-2.tar.gz", - "sha256": "f3e9781e84e114b7a88eb099825936cc5ae7276bbba5af94d35adb1b3ea2ccdd" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "Rcpp", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/Rcpp_1.0.0.tar.gz", - "sha256": "b7378bf0dda17ef72aa3f2a318a9cb5667bef50b601dc1096431e17426e18bc2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "RcppArmadillo", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/RcppArmadillo_0.9.200.7.0.tar.gz", - "sha256": "57ecc51f966b10371c536278e13a2cd421e31664fdff764c310818d8b627a086" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "RcppEigen", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/RcppEigen_0.3.3.5.0.tar.gz", - "sha256": "e5c6af17770c5f57b7cf2fba04ad1a519901b446e8138bfff221952458207f05" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "relimp", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/relimp_1.0-5.tar.gz", - "sha256": "acac7cf72ea39916761b51c825db0ffcb2bb1640e0a04086831fb78e9e40b679" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rematch", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rematch_1.0.1.tar.gz", - "sha256": "a409dec978cd02914cdddfedc974d9b45bd2975a124d8870d52cfd7d37d47578" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "remotes", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/remotes_2.0.2.tar.gz", - "sha256": "aab33b1d1ec24a1a7656c3b2c9ec69227b24ab01163bd9348da1e4cb61ed5267" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rex", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rex_1.1.2.tar.gz", - "sha256": "bd3c74ceaf335336f5dd04314d0a791f6311e421a2158f321f5aab275f539a2a" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rjson", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rjson_0.2.20.tar.gz", - "sha256": "3a287c1e5ee7c333ed8385913c0a307daf99335fbdf803e9dcca6e3d5adb3f6c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rlang", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rlang_0.4.0.tar.gz", - "sha256": "9748a4a217548bbe5631c18fd88c94811950446f798ff21fb327703aebaa150d" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rpf", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rpf_0.62.tar.gz", - "sha256": "71f2c4be743b04b694b6fca0bbb8fcbaac62385ddd4adaa54c7199632287f8ed" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rprojroot", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rprojroot_1.3-2.tar.gz", - "sha256": "df5665834941d8b0e377a8810a04f98552201678300f168de5f58a587b73238b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rstudioapi", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rstudioapi_0.9.0.tar.gz", - "sha256": "5149a2830ae7134c396ce64764b263cf9f348d4399f53da3804f40d7d5bec13e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "RUnit", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/RUnit_0.4.32.tar.gz", - "sha256": "23a393059989000734898685d0d5509ece219879713eb09083f7707f167f81f1" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "sn", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/sn_1.5-4.tar.gz", - "sha256": "46677ebc109263a68f62b5cf53ec59916cda490e5bc5bbb08276757a677f8674" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "snow", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/snow_0.4-3.tar.gz", - "sha256": "8512537daf334ea2b8074dbb80cf5e959a403a78d68bc1e97664e8a4f64576d8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "som", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/som_0.3-5.1.tar.gz", - "sha256": "a6f4c0e5b36656b7a8ea144b057e3d7642a8b71972da387a7133f3dd65507fb9" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "sourcetools", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/sourcetools_0.1.7.tar.gz", - "sha256": "47984406efb3b3face133979ccbae9fefb7360b9a6ca1a1c11473681418ed2ca" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "sp", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/sp_1.3-1.tar.gz", - "sha256": "57988b53ba8acc35f3912d62feba4b929a0f757c6b54080c623c5d805e0cb59f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "SparseM", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/SparseM_1.77.tar.gz", - "sha256": "a9329fef14ae4fc646df1f4f6e57efb0211811599d015f7bc04c04285495d45c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "StanHeaders", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/StanHeaders_2.19.0.tar.gz", - "sha256": "a0ab8f996a7a903a37491f6e4e8cf8b9f51bf0c13a5326171fab90692fe14592" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "stringi", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/stringi_1.3.1.tar.gz", - "sha256": "32df663bb6e9527e1ac265eec2116d26f7b7e62ea5ae7cc5de217cbb8defc362" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "stringr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/stringr_1.4.0.tar.gz", - "sha256": "87604d2d3a9ad8fd68444ce0865b59e2ffbdb548a38d6634796bbd83eeb931dd" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "SuppDists", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/SuppDists_1.1-9.4.tar.gz", - "sha256": "fcb571150af66b95dcf0627298c54f7813671d60521a00ed157f63fc2247ddb9" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "sys", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/sys_3.0.tar.gz", - "sha256": "b05f576923b7581976fce19b707d428dc8315fcd3805255fe9e3566c8a0b18bc" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "TH.data", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/TH.data_1.0-10.tar.gz", - "sha256": "618a1c67a30536d54b1e48ba3af46a6edcd6c2abef17935b5d4ba526a43aff55" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "truncnorm", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/truncnorm_1.0-8.tar.gz", - "sha256": "49564e8d87063cf9610201fbc833859ed01935cc0581b9e21c42a0d21a47c87e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ucminf", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ucminf_1.1-4.tar.gz", - "sha256": "a2eb382f9b24e949d982e311578518710f8242070b3aa3314a331c1e1e7f6f07" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "utf8", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/utf8_1.1.4.tar.gz", - "sha256": "f6da9cadfc683057d45f54b43312a359cf96ec2731c0dda18a8eae31d1e31e54" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "VGAM", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/VGAM_1.1-1.tar.gz", - "sha256": "de192bd65a7e8818728008de8e60e6dd3b61a13616c887a43e0ccc8147c7da52" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "viridisLite", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/viridisLite_0.3.0.tar.gz", - "sha256": "780ea12e7c4024d5ba9029f3a107321c74b8d6d9165262f6e64b79e00aa0c2af" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "whisker", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/whisker_0.3-2.tar.gz", - "sha256": "484836510fcf123a66ddd13cdc8f32eb98e814cad82ed30c0294f55742b08c7c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "withr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/withr_2.1.2.tar.gz", - "sha256": "41366f777d8adb83d0bdbac1392a1ab118b36217ca648d3bb9db763aa7ff4686" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "wordcloud", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/wordcloud_2.6.tar.gz", - "sha256": "53716954430acd4f164bfd8eacd7068a908ee3358293ded6cd992d53b7f72649" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "xfun", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/xfun_0.5.tar.gz", - "sha256": "8ba224bbf2490f7bb478fd0436592506cb98ec1fc2fc6a7ea2298344d85579f2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "XML", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/XML_3.98-1.19.tar.gz", - "sha256": "81b1c4a2df24c5747fa8b8ec2d76b4e9c3649b56ca94f6c93fbd106c8a72beab" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "xml2", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/xml2_1.2.2.tar.gz", - "sha256": "3050f147c4335be2925a576557bbda36bd52a5bba3110d47b740a2dd811a78f4" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "xtable", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/xtable_1.8-3.tar.gz", - "sha256": "53b2b0fff8d7a8bba434063c2a01b867f510a4389ded2691fbedbc845f08c325" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "yaml", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/yaml_2.2.0.tar.gz", - "sha256": "55bcac87eca360ab5904914fcff473a6981a1f5e6d2215d2634344d0ac30c546" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "zeallot", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/zeallot_0.1.0.tar.gz", - "sha256": "439f1213c97c8ddef9a1e1499bdf81c2940859f78b76bc86ba476cebd88ba1e9" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "zip", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/zip_2.0.0.tar.gz", - "sha256": "06bd15ef39d6ee552d568ea9e2d3d77360b3984a53528f529f14782694e90629" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "zoo", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/zoo_1.8-4.tar.gz", - "sha256": "b1d88c169d210b99d747e802f96f7a2a7f5d8e6f1c0b42776e32e269d065dcdf" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "abtest", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/abtest_0.1.3.tar.gz", - "sha256": "f5c6d63de0c7c3d9a3fe86861e34e30cde1b926c3c3715712d5ecd4bdd2ef4cb" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "askpass", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/askpass_1.1.tar.gz", - "sha256": "db40827d1bdbb90c0aa2846a2961d3bf9d76ad1b392302f9dd84cc2fd18c001f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "BayesFactor", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/BayesFactor_0.9.12-4.2.tar.gz", - "sha256": "6fe8d19113084b1bb278daa824603db5b93ee02d55a24214a82f081dcf1e08fc" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "BSDA", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/BSDA_1.2.0.tar.gz", - "sha256": "a2deea4f772d0db74f35ea502ea8cd827b455ac4c795591c69b210c5bc1f433f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "cli", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/cli_1.0.1.tar.gz", - "sha256": "ef80fbcde15760fd55abbf9413b306e3971b2a7034ab8c415fb52dc0088c5ee4" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "desc", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/desc_1.2.0.tar.gz", - "sha256": "e66fb5d4fc7974bc558abcdc107a1f258c9177a29dcfcf9164bc6b33dd08dae8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ellipsis", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ellipsis_0.1.0.tar.gz", - "sha256": "e6f1f30390182b36664b097b5fbf6e95897a766b1ddfa774d3b507f42e26895f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "etm", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/etm_1.0.4.tar.gz", - "sha256": "813a774fdd344b2c25362603c6adedd65a2e3c9dddf9d5c90791d63bd6004173" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "fitdistrplus", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/fitdistrplus_1.0-14.tar.gz", - "sha256": "85082590f62aa08d99048ea3414c5cc1e5b780d97b3779d2397c6cb435470083" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "foreach", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/foreach_1.4.4.tar.gz", - "sha256": "c0a71090d5b70b9a95a6936091dabae9c26e1fc6b9609bfe5fb6346033905e48" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "fs", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/fs_1.2.6.tar.gz", - "sha256": "12a929d8e1c7a561d90eb0692c8a13927aa02d8f8034da6ac8a3235a3156184f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "gdata", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/gdata_2.18.0.tar.gz", - "sha256": "4b287f59f5bbf5fcbf18db16477852faac4a605b10c5284c46b93fa6e9918d7f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "GeneNet", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/GeneNet_1.2.13.tar.gz", - "sha256": "3798caac3bef7dc87f97b3628eb29eb12365d571ce0837b5b6285b0be655a270" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "glmnet", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/glmnet_2.0-16.tar.gz", - "sha256": "a54ccd802fce6625f3b69d747b28efe62ed8cc23397a5f8df4777d177e2839af" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "gnm", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/gnm_1.1-0.tar.gz", - "sha256": "b43a91fbe51848a414858ece413d2886d2fbbed4c2d88da0243c350275e7a705" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "gridExtra", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/gridExtra_2.3.tar.gz", - "sha256": "81b60ce6f237ec308555471ae0119158b115463df696d2eca9b177ded8988e3b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "htmltools", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/htmltools_0.3.6.tar.gz", - "sha256": "44affb82f9c2fd76c9e2b58f9229adb003217932b68c3fdbf1327c8d74c868a2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "htmlwidgets", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/htmlwidgets_1.3.tar.gz", - "sha256": "f1e4ffabc29e6cfe857f627da095be3cfcbe0e1f02ae75e572f10b4a026c5a12" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "igraph", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/igraph_1.2.4.tar.gz", - "sha256": "1048eb26ab6b592815bc269c1d91e974c86c9ab827ccb80ae0a40042019592cb" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "kknn", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/kknn_1.3.1.tar.gz", - "sha256": "22840e70ec2afa40371e274b583634c8f6d27149a87253ee411747d5db78f3db" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "later", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/later_0.8.0.tar.gz", - "sha256": "6b2a28b43c619b2c7890840c62145cd3a34a7ed65b31207fdedde52efb00e521" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "latticeExtra", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/latticeExtra_0.6-28.tar.gz", - "sha256": "780695323dfadac108fb27000011c734e2927b1e0f069f247d65d27994c67ec2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "lavaan", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/lavaan_0.6-3.tar.gz", - "sha256": "bffb89d7fb70f6bde5c984009803b3ab9b9802cc2608d2acb1f887b0a7298843" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "lifecycle", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/lifecycle_0.1.0.tar.gz", - "sha256": "961c28c016d54beee496572a88602fe94d8456ee6455ac88cb2e0fc3273c3387" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "lmtest", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/lmtest_0.9-36.tar.gz", - "sha256": "be9f168d6554e9cd2be0f9d8fc3244f055dce90d1fca00f05bcbd01daa4ed56b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "maptools", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/maptools_0.9-5.tar.gz", - "sha256": "5d9511f09fb49d57a51f28495b02239800596a4fcfad7b03ee1074d793657bdd" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "markdown", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/markdown_0.9.tar.gz", - "sha256": "3068c6a41ca7a76cbedeb93b7371798f4d8437eea69a23c0ed5204c716d1bf23" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "minqa", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/minqa_1.2.4.tar.gz", - "sha256": "cfa193a4a9c55cb08f3faf4ab09c11b70412523767f19894e4eafc6e94cccd0c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "OpenMx", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/OpenMx_2.13.2.tar.gz", - "sha256": "b349b4100cf3349c630df523af1c3c9d7ccf33158bb0ed38fd927628780abe70" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "openssl", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/openssl_1.2.1.tar.gz", - "sha256": "7bca442592c377843c2fda9078cac4277aa91b967c583cff8d4fa2927120ea7a" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "openxlsx", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/openxlsx_4.1.0.tar.gz", - "sha256": "ab7b127353061a0e1cd621783366ffdd7c858c6df31cbbdd39aaa353af10ffd8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ordinal", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ordinal_2018.8-25.tar.gz", - "sha256": "70902dd51d4bcc00064ca407f2136744db71c5d4e8c35f15a443229e194c9b0d" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "plyr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/plyr_1.8.4.tar.gz", - "sha256": "60b522d75961007658c9806f8394db27989f1154727cb0bb970062c96ec9eac5" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "processx", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/processx_3.2.1.tar.gz", - "sha256": "14a7305c4ec5a78a7a656d79e9ff0fc1d134671c924ae5941e6cab634ef472ea" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "promises", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/promises_1.0.1.tar.gz", - "sha256": "c2dbc7734adf009377a41e570dfe0d82afb91335c9d0ca1ef464b9bdcca65558" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "purrr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/purrr_0.3.0.tar.gz", - "sha256": "aa7d1b2b75eb2d4179c8d8108a41982b2d153bfefef404f3c4b961a45872eb57" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "quantreg", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/quantreg_5.38.tar.gz", - "sha256": "815b14f6fe8c8e8df36a5b2c307539f81554a6d57650021e630db890c4b47bef" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "R.matlab", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/R.matlab_3.6.2.tar.gz", - "sha256": "1ba338f470a24b7f6ef68cadbd04eb468ead4a689f263d2642408ad591b786bb" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "reshape2", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/reshape2_1.4.3.tar.gz", - "sha256": "8aff94c935e75032344b52407593392ddd4e16a88bb206984340c816d42c710e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "Rsolnp", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/Rsolnp_1.16.tar.gz", - "sha256": "3142776062beb8e2b45cdbc4fe6e5446b6d33505253d79f2890fe4178d9cf670" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rversions", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rversions_2.0.0.tar.gz", - "sha256": "b50c321d9e973284ae6b1d0c89bd46a40f5174de51fb28e3c77cd12ef34f6f56" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "sandwich", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/sandwich_2.5-0.tar.gz", - "sha256": "6cc144af20739eb23e5539010d3833d7c7fc53cbca2addb583ab933167c11399" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "scales", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/scales_1.0.0.tar.gz", - "sha256": "0c1f4a14edd336a404da34a3cc71a6a9d0ca2040ba19360c41a79f36e06ca30c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "semTools", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/semTools_0.5-1.tar.gz", - "sha256": "d11e3e94ea68199fe1a3ccaa8b640b0ac487f82dd724da6a900c2284b8070152" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "sessioninfo", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/sessioninfo_1.1.1.tar.gz", - "sha256": "166b04678448a7decd50f24afabe5e2ad613e3c55b180ef6e8dd7a870a1dae48" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "survey", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/survey_3.35-1.tar.gz", - "sha256": "11e5ddde9c8c21dfaed0b1247036e068ad32782c76ff71f7937eb7585dd364db" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "testthat", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/testthat_2.2.1.tar.gz", - "sha256": "67ee0512bb312695c81fd74338bb8ce9e2e58763681ddbcdfdf35f52dfdb0b78" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "tidyselect", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/tidyselect_0.2.5.tar.gz", - "sha256": "5ce2e86230fa35cfc09aa71dcdd6e05e1554a5739c863ca354d241bfccb86c74" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "vcd", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/vcd_1.4-4.tar.gz", - "sha256": "a561adf120b5ce41b66e0c0c321542fcddc772eb12b3d7020d86e9cd014ce9d2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "vcdExtra", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/vcdExtra_0.7-1.tar.gz", - "sha256": "0cac977f412e84c5f2625a14e381df7a98498108ebbcc816ceb53db8214c7d98" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "vctrs", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/vctrs_0.2.0.tar.gz", - "sha256": "5bce8f228182ecaa51230d00ad8a018de9cf2579703e82244e0931fe31f20016" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "visNetwork", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/visNetwork_2.0.8.tar.gz", - "sha256": "89ca01cabfcb40513314580daf25dccda0bd8fc74cbe8789e1d7ed6426093051" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "xopen", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/xopen_1.0.0.tar.gz", - "sha256": "e207603844d69c226142be95281ba2f4a056b9d8cbfae7791ba60535637b3bef" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "xts", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/xts_0.11-2.tar.gz", - "sha256": "12772f6a66aab5b84b0665c470f11a3d8d8a992955c027261cfe8e6077ee13b8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "BDgraph", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/BDgraph_2.55.tar.gz", - "sha256": "a8eed2a1116f073193931f9b5ac5c005682907380896dcd404b5dc8435719d01" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "callr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/callr_3.1.1.tar.gz", - "sha256": "c9bc22719dbc7a6746d370a2c7f353561d2f25e34fe4079f50eb453594c38196" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "d3Network", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/d3Network_0.5.2.1.tar.gz", - "sha256": "5c798dc0c87c6d574abb7c1f1903346e6b0fec8adfd1df7aef5e4f9e7e3a09be" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "doParallel", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/doParallel_1.0.14.tar.gz", - "sha256": "cbbb7f37606d608a9603915ee65587f8ed4bb4a8405ecfaa7f33b8c423d11207" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "doSNOW", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/doSNOW_1.0.16.tar.gz", - "sha256": "161434ecd55f04d6b070da784b222a7686c914b73de558eef6048a229022398e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "emmeans", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/emmeans_1.3.2.tar.gz", - "sha256": "c52d24bb8d1954024a14ba1f38673a7d71660bed4f12cc0230b93a7800f0e655" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "Epi", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/Epi_2.34.tar.gz", - "sha256": "fcbb104f5352feeaf7a2284548be515cf269652ea71b177f054ad9dbed752fb3" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ggm", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ggm_2.3.tar.gz", - "sha256": "832ffe81ff87c6f1a6644e689ebbfb172924b4c4584ac8108d1244d153219ed8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "hms", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/hms_0.4.2.tar.gz", - "sha256": "a57820b3e3221e973cba9500b4ad7953730110ee398693d150af833f26d5d0bc" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "httpuv", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/httpuv_1.4.5.1.tar.gz", - "sha256": "76739878c8583527a3aa6124389ba103acc91b030635290397f3b6c924200d57" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "httr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/httr_1.4.0.tar.gz", - "sha256": "d633f1425da514f65f3b8c034ae0a8b6911995009840c6bb9657ceedb99ddb48" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "huge", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/huge_1.3.0.tar.gz", - "sha256": "9095151b4fc57f93dc5b120e2e7f51e46938756fc917c6201a5d599fd5c9faa2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "IsingSampler", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/IsingSampler_0.2.tar.gz", - "sha256": "1c3152763f3478a3f6ac165983c38fe2c0077f05413ecdd3d47b4bcc6e597c9b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "knitr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/knitr_1.21.tar.gz", - "sha256": "124c95914f6039bc8801ab1ed7f9fc5beda6c2fcc92bb18a5298c6f948acfe77" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "kutils", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/kutils_1.67.tar.gz", - "sha256": "7509b68357d36bf8bde6a9021e0528c631e389e2af6836ae8c3a633cb513ffa0" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "lme4", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/lme4_1.1-20.tar.gz", - "sha256": "44f45f5cd20ec6a50bf96a939b1db44b1a180dbc871a5e3042baf7a107016b2c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "multcomp", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/multcomp_1.4-8.tar.gz", - "sha256": "a20876619312310e9523d67e9090af501383ce49dc6113c6b4ca30f9c943a73a" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "parcor", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/parcor_0.2-6.tar.gz", - "sha256": "a06f1df3d41a9e00dd42cd4dfd14187c2b6c9c137b7186566520b72dd234fa6d" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "pbkrtest", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/pbkrtest_0.4-7.tar.gz", - "sha256": "5cbb03ad2b2468720a5a610a0ebda48ac08119a34fca77810a85f554225c23ea" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "pillar", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/pillar_1.3.1.tar.gz", - "sha256": "b338b55f956dd7134f379d39bb94dfb25e13cf27999d6a6e6dc9f292755acbf6" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "pkgbuild", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/pkgbuild_1.0.2.tar.gz", - "sha256": "1a3e2a321742aab8dbda150f952c61b2a04e41618e9517e95d229f7ebaca39c4" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "pkgload", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/pkgload_1.0.2.tar.gz", - "sha256": "3186564e690fb05eabe76e1ac0bfd4312562c3ac8794b29f8850399515dcf27c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "progress", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/progress_1.2.2.tar.gz", - "sha256": "b4a4d8ed55db99394b036a29a0fb20b5dd2a91c211a1d651c52a1023cc58ff35" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rcmdcheck", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rcmdcheck_1.3.2.tar.gz", - "sha256": "9e9ed727450bea3ca78f652bf3d0b748e4ce0376e87d4ff5e7b082644eb3417b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "regsem", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/regsem_1.3.3.tar.gz", - "sha256": "5de6afbff541ba9ed7355e5488e7c3c701da0d4e7554e9335d42a5c6097e178a" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "relaimpo", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/relaimpo_2.2-3.tar.gz", - "sha256": "09f745fac3285c8633675687130357c279df80a1d1d069bd7fd155e8a9726e5d" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rockchalk", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rockchalk_1.8.144.tar.gz", - "sha256": "cb5e6c87ec95589f2b02da7ed7a5a67ec125e132100c8ae6762fad52820db71d" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "roxygen2", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/roxygen2_6.1.1.tar.gz", - "sha256": "ed46b7e062e0dfd8de671c7a5f6d120fb2b720982e918dbeb01e6985694c0273" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "shiny", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/shiny_1.2.0.tar.gz", - "sha256": "fece84fdeb6e9009d4f6b95b4e7c1bea1754ecc9dd79685dc17451f6e54666f1" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "shinyAce", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/shinyAce_0.3.3.tar.gz", - "sha256": "f24c992cfe7a9c6d69cb8c7d5ca86269f7e0626728b85587f3d4263238e6060b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "shinyBS", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/shinyBS_0.61.tar.gz", - "sha256": "51be29541e066d30c66e243393f20b0da705eba1b7ce7eeadea993bb2aa91166" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "shinyjs", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/shinyjs_1.0.tar.gz", - "sha256": "286b11136bc999738592d01f980e7db86930fb3216effc680688829865bc7f84" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "tibble", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/tibble_2.0.1.tar.gz", - "sha256": "7ab2cc295eecf00a5310993c99853cd6622ad468e7a60d004b8a73957a713d13" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "TTR", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/TTR_0.23-4.tar.gz", - "sha256": "eb17604da986213b3b924f0af65c3d089502a658a253ee34f6b8f6caccf6bfa2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "wTO", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/wTO_1.6.3.tar.gz", - "sha256": "d69672bb02b1a9b97c4a38c8ea6b37d6698f4ba1514b88cbbb918cb3cee0ebb1" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "arm", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/arm_1.10-1.tar.gz", - "sha256": "6f1158c9295e65bd649139224497d3356189b931ff143f9b374daae72548776f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "cellranger", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/cellranger_1.1.0.tar.gz", - "sha256": "5d38f288c752bbb9cea6ff830b8388bdd65a8571fd82d8d96064586bd588cf99" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "covr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/covr_3.3.1.tar.gz", - "sha256": "9ae19c58ec0999a71bde5c6c27689a4cc86011ad0b06c3d5343d043eca3e6d3b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "dplyr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/dplyr_0.8.0.1.tar.gz", - "sha256": "8408889d31a32527dbd846b3a6d995a2a7db7a51618ff28e61747afcb25ccd5c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "forcats", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/forcats_0.4.0.tar.gz", - "sha256": "7c83cb576aa6fe1379d7506dcc332f7560068b2025f9e3ab5cd0a5f28780d2b2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ggplot2", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ggplot2_3.1.0.tar.gz", - "sha256": "49e77ccbe1ee9e4278312b001ad34aa1d93a3d98a90aaefcb595da20b2195ed7" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ggrepel", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ggrepel_0.8.0.tar.gz", - "sha256": "6386606e716d326354a29fcb6cd09f9b3d3b5e7c5ba0d5f7ff35416b1a4177d4" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "gh", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/gh_1.0.1.tar.gz", - "sha256": "f3c02b16637ae390c3599265852d94b3de3ef585818b260d00e7812595b391d2" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "htmlTable", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/htmlTable_1.13.1.tar.gz", - "sha256": "689f32b65da6a57ad500e8d9ef3309d346401dca277c6b264a46c8d7c75884d0" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "jomo", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/jomo_2.6-7.tar.gz", - "sha256": "6e83dab51103511038a3e9a3c762e00cc45ae7080c0a0f64e37bcea8c488db53" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "lmerTest", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/lmerTest_3.1-0.tar.gz", - "sha256": "2bdd4e8c1b9f88653dd39e5ee919878bb45bac857515130946cb17d52b437fda" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "mi", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/mi_1.0.tar.gz", - "sha256": "34f44353101e8c3cb6bf59c5f4ff5b2391d884dcbb9d23066a11ee756b9987c0" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "miniUI", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/miniUI_0.1.1.1.tar.gz", - "sha256": "452b41133289f630d8026507263744e385908ca025e9a7976925c1539816b0c0" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "quantmod", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/quantmod_0.4-13.tar.gz", - "sha256": "60fb13821c9d8d5bea34223b18757f04787f4440cb82946bb9559d6fd26b5499" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "readr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/readr_1.3.1.tar.gz", - "sha256": "33f94de39bb7f2a342fbb2bd4e5afcfec08798eac39672ee18042ac0b349e4f3" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "readxl", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/readxl_1.3.0.tar.gz", - "sha256": "8379d1026dcfc662d073eb1c69ed1d90aa6439d6cb3c6fc1b5d1db4f51b3fadc" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "sem", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/sem_3.1-9.tar.gz", - "sha256": "4a33780202506543da85877cd2813250114420d6ec5e75457bc67477cd332cb9" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "tidyr", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/tidyr_0.8.2.tar.gz", - "sha256": "99a508d0539390364789c5f4835b36c4a383927f0ec1648e2a4636c1cc6e490f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "tseries", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/tseries_0.10-46.tar.gz", - "sha256": "12940afd1d466401160e46f993ed4baf28a42cef98d3757b66ee15e916e07222" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "usethis", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/usethis_1.4.0.tar.gz", - "sha256": "96f33cc00e9126e5cd891b6052cbb7e23df64f4f32df79777fe9773dfa644dbd" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "viridis", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/viridis_0.5.1.tar.gz", - "sha256": "ddf267515838c6eb092938133035cee62ab6a78760413bfc28b8256165701918" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "broom", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/broom_0.5.1.tar.gz", - "sha256": "da9e6bf7cb8f960b83309cf107743976cc32b54524675f6471982abe3d1aae2e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "colourpicker", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/colourpicker_1.0.tar.gz", - "sha256": "f1dacbafb05c09f61b9bdd0fdcee5344409759b042a71ec46d7c9e3710107b7c" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "conting", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/conting_1.6.1.tar.gz", - "sha256": "02900f2b87b931da7f6561fdde0d236d9227054d68013f4d54ea77a9227f866f" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "cowplot", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/cowplot_0.9.4.tar.gz", - "sha256": "fb57091f4d089797bafa4aeb71371390761bcc40de180c26f6adf94d15a76a7b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "crosstalk", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/crosstalk_1.0.0.tar.gz", - "sha256": "b31eada24cac26f24c9763d9a8cbe0adfd87b264cf57f8725027fe0c7742ca51" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "DT", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/DT_0.8.tar.gz", - "sha256": "90195054148806cf31c7db5c41f72d5389c75adc0b1183606a9babd2c6ae8e21" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "ggedit", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/ggedit_0.3.0.tar.gz", - "sha256": "f66704142b6d79e926cbb5c85eb4d6dffc97c08b68ef2ca1c74c1e52a7bb2aed" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "haven", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/haven_2.1.0.tar.gz", - "sha256": "c0a1cf1b039549fb3ad833f9644ed3f142790236ad755d2ee7bd3d8109e3ae74" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "Hmisc", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/Hmisc_4.2-0.tar.gz", - "sha256": "9e9614673288dd00295f250fa0bf96fc9e9fed692c69bf97691081c1a01411d9" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "mitml", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/mitml_0.3-7.tar.gz", - "sha256": "c6f796d0059f1b093b599a89d955982fa257de9c45763ecc2cbbce10fdec1e7b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "qgraph", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/qgraph_1.6.1.tar.gz", - "sha256": "ea2c561cd3215ec4f24cb02c84a3991937bf9816fca51aec489da0f5bf079fc7" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "rio", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/rio_0.5.16.tar.gz", - "sha256": "d3eb8d5a11e0a3d26169bb9d08f834a51a6516a349854250629072d59c29d465" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "semPlot", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/semPlot_1.1.1.tar.gz", - "sha256": "82ef389fc8bacb6dcdea1b4d32c04156a79857bd7a7018a26eee3aa9562e78f5" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "car", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/car_3.0-2.tar.gz", - "sha256": "df59a9ba8fed67eef5ddb8f92f2b41745df715d5695c71d562d7031513f37c50" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "devtools", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/devtools_2.0.1.tar.gz", - "sha256": "0ef5f1cfca9f6184d32ba62d69b42f1cc574c25807cc815f0eed27cb22bedadb" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "graphicalVAR", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/graphicalVAR_0.2.2.tar.gz", - "sha256": "681d218db5f4498efe387dbf45462fbddf96221953fc8d4443ec5feadbc2f0cb" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "heplots", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/heplots_1.3-5.tar.gz", - "sha256": "964629cba7feadbf3ac223e417310016e86067da4bbf11ad3c213e63ee74d0ef" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "IsingFit", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/IsingFit_0.3.1.tar.gz", - "sha256": "8741d65b63818c927819155f13a62d21f7d7f4942b9d218e6f93ce12eeff2ddf" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "mgm", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/mgm_1.2-5.tar.gz", - "sha256": "aab2e9e2bceea1bf5b127718399814a2928e5ade9f686a24c67762652a1e4bb8" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "mice", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/mice_3.3.0.tar.gz", - "sha256": "ddaf7f01f5606f3e15af05066e2f6c3ac5b6bdcc78f019e3890dab32f1ba11dc" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "NetworkComparisonTest", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/NetworkComparisonTest_2.0.1.tar.gz", - "sha256": "4a78284fac6a89cd805712d59ad197cc386322afff0a5e4b96c9add8aea5d825" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "NetworkToolbox", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/NetworkToolbox_1.2.3.tar.gz", - "sha256": "f40f69e03cce1a1548aa1fd4364a3746be66455c8988b7e9c21aab94c7cdb051" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "onewaytests", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/onewaytests_2.0.tar.gz", - "sha256": "b4dd9da576311ab9fdeb1824d9c8dbb8999f7ff63264a8936c6b8cdb30977660" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "weights", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/weights_1.0.tar.gz", - "sha256": "8cb0e72edce061886ab67190c621a7da5caace787719a6a0cecf7638af5b0605" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "afex", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/afex_0.23-0.tar.gz", - "sha256": "e76e21795d7eaf5959c016429373c92bdc34c24e98136f420096eb60c8d1647b" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "candisc", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/candisc_0.8-0.tar.gz", - "sha256": "b1821c11b2fe2a1758015e2f1a626cdeb3b9966c3d09269c8339a483375f0543" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "smacof", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/smacof_1.10-8.tar.gz", - "sha256": "ebcb27519c11a3cacebfd84793796ffa40d6a2aefaceadfe43a9eac7aebb7de0" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "networktools", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/networktools_1.2.0.tar.gz", - "sha256": "eab7c77e4a79d41553336dd63084ba7be2af6327974b195a439946baf7af7b08" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - - { - "name": "bootnet", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "http://static.jasp-stats.org/RPkgs/bootnet_1.2.tar.gz", - "sha256": "07cbc7be1c2256d0cfc2c98d1d9d0aeb51d6388d0dcf60361873ec716286e51e" - } - ], - "build-commands": [ "R CMD INSTALL ." ] - }, - diff --git a/Tools/flatpak/flatpak_screenshot_0_small.png b/Tools/flatpak/flatpak_screenshot_0_small.png new file mode 100644 index 0000000000..a3d60c9ccd Binary files /dev/null and b/Tools/flatpak/flatpak_screenshot_0_small.png differ diff --git a/Tools/flatpak/gather-r-package-info.R b/Tools/flatpak/gather-r-package-info.R deleted file mode 100644 index 42072f1db4..0000000000 --- a/Tools/flatpak/gather-r-package-info.R +++ /dev/null @@ -1,426 +0,0 @@ -options(warn=1) #print warnings as they occur -options(nCpus=parallel::detectCores()) - -CRAN <- #"https://cran.rstudio.com/" - "https://cran.r-project.org/" # - - -#define vars -expEnv <- NULL -downloaded <- NULL -pkgDeps <- NULL -available_pkgs <- NULL -destDir <- NULL -destTmpDir <- NULL -pkgs <- NULL -base_pkgs <- NULL -specials <- NULL - -initialize <- function() -{ - #Create necessary environments (only hash available) - expEnv <<- new.env(hash = TRUE, parent = parent.frame()) - downloaded <<- new.env(hash = TRUE, parent = parent.frame()) - pkgDeps <<- new.env(hash = TRUE, parent = parent.frame()) - - #what packages are available? Do we care? - available_pkgs <<- available.packages(repos = CRAN) - destDir <<- "pkg-source-files/" - destTmpDir <<- "pkg-source-tmp-files/" - - # Define the base packages. These are packages which come with R upon install - # of R. These packages include: "base", "compiler", "datasets", "graphics", - # "grDevices", "grid", "methods", "parallel", "splines", "stats", "stats4", - # "tcltk", "tools", and "utils". - # - # NOTE: there are Priority = "recommended" packages as well. If these packages - # are missing from the system install, this script might fail. Downloading and - # installing the 'recommended' packages can be difficult between R versions. - base_pkgs <<- unname(utils::installed.packages()[utils::installed.packages()[, "Priority"] %in% c("base", "recommended"), "Package"]) - - cat('get the packages that JASP expects and put them in an env that includes a specific version\n') - source("../../Engine/jaspBase/R/packagecheck.R", local=TRUE) - expected <- .expectedPackages() - pkgs <<- expected[,1] - - for (curPkg in pkgs) - { - expVersion <- expected[curPkg, "Version"] - expEnv[[curPkg]] <- expVersion - } - - if(!dir.exists(destDir)) - dir.create(destDir) - - if(!dir.exists(destTmpDir)) - dir.create(destTmpDir) -} - - -defineSpecials <- function() -{ - specials <<- new.env(hash = TRUE, parent = parent.frame()) - specials[['bstats']] <- list(type='github', commit='1b0b925d0404537b908a6380b70d80382df2d374', repo='AlexanderLyNL/bstats' ) - specials[['flexplot']] <- list(type='github', commit='163137fe30d9541234eb0053d6d86e1f96cd3dc5', repo='dustinfife/flexplot' ) - specials[['Bayesrel']] <- list(type='github', commit='06bfd2fe3e7dba988adbf2e328131067b8d50361', repo='juliuspf/Bayesrel' ) - specials[['stanova']] <- list(type='github', commit='3e5635816fb2e4cda06704778e5bcd382f14717d', repo='bayesstuff/stanova' ) - #specials[['afex']] <- list(type='github', commit='71e22f0020399de1b35189d7c0dd4e5a2729b843', repo='singmann/afex' ) - specials[['ggpol']] <- list(type='github', commit='dea9db2503b04b81dbc746fdeccf92e9849ce64b', repo='jasp-stats/ggpol' ) # temporary fix for conflicting ggplot2 dependencies in jasp 0.12.2. Should be removed after that release and shit should be fixed! - #specials[['RoBMA']] <- list(type='github', commit='7685d4d203a46f259b4cda2c492c8235397c80eb', repo='FBartos/RoBMA' ) - -} - -getPkgVersion <- function(pkgName) -{ - if(!exists(pkgName, where=expEnv, inherits=FALSE)) - { - # so we do not know what version we need... Because this pkg was unexpected - cat(paste0("Checking version of pkg ", pkgName, " in available_pkgs\n")) - expEnv[[pkgName]] <- available_pkgs[[pkgName, "Version"]] - cat(paste0("Couldn't find version of ",pkgName," in expected packages so took it from availablePackages: ", expEnv[[pkgName]], '\n')) - } - - return(expEnv[[pkgName]]) -} - -downloadPkgGithub <- function(pkgName) -{ - # example https://github.com/quentingronau/abtest/tarball/503c50e96768a0134b755747e0421d820cc1a115 - repo <- specials[[pkgName]]$repo - commit <- specials[[pkgName]]$commit - succes <- FALSE - tarballUrl <- paste0('https://github.com/', repo, '/tarball/', commit) - destFile <- paste0(destTmpDir, '/', pkgName, '_', commit, '.tar.gz') - - if(!file.exists(destFile)) - { - cat(paste0('For pkg ', pkgName, ' getting github tarball download from "',tarballUrl,'" to: "', destFile, '"', '\n')) - - tryCatch(error=function(e) e, exp= - { - download.file(url=tarballUrl, destfile=destFile); - succes <- TRUE; - }) - - if(!succes) - stop("Failed to get pkg sources for '", pkgName, "' from github for repo: '", repo, "' and commit '", commit, "'") - } - - return(destFile) -} - -downloadPkgCran <- function(curPkg) -{ - version <- getPkgVersion(curPkg) - filePkg <- paste0(curPkg, "_", expEnv[[curPkg]],".tar.gz") - destFile <- paste0(destDir, filePkg) - - downloaded[[curPkg]] <- list(version=version, fileName=filePkg, destFile=destFile, downloadUrl=paste0("http://static.jasp-stats.org/RPkgs/", filePkg), sha256='') - - if(!file.exists(destFile)) - { - cat(paste0("File ",destFile, " does not exist yet, try to get it from CRAN.\n")) - curVer <- paste0(CRAN, 'src/contrib/', filePkg) - oldVer <- paste0(CRAN, 'src/contrib/Archive/', curPkg, '/', filePkg) - succes <- FALSE - - cat(paste0('For pkg ', curPkg, ' trying download from "',curVer,'"\n')) - - tryCatch(error=function(e) e, exp= - { - download.file(url=curVer, destfile=destFile); - succes <- TRUE; - }) - - if(!succes) - { - cat(paste0('Download failed, now trying: "',oldVer,'"\n')) - tryCatch(error=function(e) e, exp={ - download.file(url=oldVer, destfile=destFile); - succes <- TRUE; - }) - } - - if(!succes) - stop("Both downloads failed...") - } - - sha256sumOutput <- system2('sha256sum', args=destFile, stdout=TRUE) - downloaded[[curPkg]]$sha256 <- strsplit(sha256sumOutput, ' ')[[1]][[1]] - - return(destFile) - -} - - -downloadPkg <- function(pkgName) -{ - if(is.null(specials)) defineSpecials() - - filename <- "???" - - #check if special case then go to github - filename <- ifelse( - exists(pkgName, where=specials, inherits=FALSE), - yes = downloadPkgGithub(pkgName), - no = downloadPkgCran(pkgName) - ) - - #github doesnt need to check if file downloaded because it is just a few - #otherwise try to get it from Cran if it isnt in pkg-sources yet - - return(filename) -} - -getDeps <- function(pkgName) -{ - if(pkgName %in% base_pkgs) - return(c()) - - if(exists(pkgName, where=pkgDeps, inherits=FALSE)) #Avoid double work because time is precious - { - cat(paste0('Dependencies for pkg "', pkgName, '" requested more than once...\n')) - return(pkgDeps[[pkgName]]) #in case someone wants em? - } - - #make sure the source pkg is in the pkg-source folder: - pkgFile <- downloadPkg(pkgName) - - deps <- remotes::dev_package_deps(pkgFile, repos = NULL, type = "source")$package - deps <- deps[!(deps %in% base_pkgs)] #remove base pkgs - - pkgDeps[[pkgName]] <- deps - - padding <- strrep(" ", 29 - nchar(pkgName)) - depstr <- paste(deps, sep=', ', collapse=', ') - - cat(paste0("Dependencies for pkg '", pkgName, "': ", padding, "'", depstr, "'\n")) - - return(deps) -} - - -giveOrderedDependencies <- function(addDeps=TRUE) -{ - initialize() - cat("Determing dependencies and their order\n") - - i <- 1L - while(i <= length(pkgs)) - { - curPkg <- pkgs[i] - deps <- getDeps(curPkg) - - if(addDeps) - pkgs <- append(pkgs, deps[!(deps %in% pkgs)]) - - i <- i + 1L - } - - cat('Now we must make sure that all pkgs are preceded by their dependencies and they by theirs\n') - orderedPkgs <- character() - inList <- new.env(hash = TRUE, parent = parent.frame(), size = length(pkgs)) - lastTime <- -1 - pkgs_to_order <- sort(names(pkgDeps)) - - while(length(pkgs_to_order) > 0) - { - i <- 1L - - while(i <= length(pkgs_to_order)) - { - curPkg <- pkgs_to_order[i] - deps <- pkgDeps[[curPkg]] - - if(!exists(curPkg, where=inList, inherits=FALSE)) - { - insert <- length(deps) == 0 - - if(!insert) #maybe all dependencies are alread in list - { - insert <- TRUE - - for(dep in deps) - if(!exists(dep, where=inList, inherits=FALSE)) - insert <- FALSE - } - - if(insert) - { - inList[[curPkg]] <- deps # no point in losing the deps even though we don't really need them after this - orderedPkgs <- c(orderedPkgs, curPkg) - remove(list=curPkg, envir=pkgDeps, inherits=FALSE) # We remove it from the pkgDeps env to make sure we know we finish eventually - #cat(paste0('Pkg ',curPkg,' depends on #', length(deps),' of deps {' ,paste0(deps, collapse='', sep=', '), '} and was added to ordered list\n')) - } - } - i <- i + 1L - } - - pkgs_to_order <- sort(names(pkgDeps)) - cat(paste0('pkgs_to_order was rebuilt from pkgDeps and now has length: ', length(pkgs_to_order), '\n')) - - if(lastTime == length(pkgs_to_order)) - { - cat('pkgDeps is not getting smaller anymore... Currently it consists of: "', paste(pkgs_to_order, sep=", ", collapse=", "), '"\n') - stop('list isnt decreasing in size anymore... bailing!') - } - - lastTime <- length(pkgs_to_order) - } - - orderedPkgs <- orderedPkgs[!(orderedPkgs %in% base_pkgs)] #remove base pkgs, because somehow they sneaked back in! - orderedPkgs <- orderedPkgs[!(orderedPkgs %in% c("graph"))] - #cat(paste0('Pkgs ordered by dependencies: ', paste0(orderedPkgs, sep=', ', collapse=''))) - - return(orderedPkgs); -} - -#Dont forget to add the dependencies up top -generateRCmdInstall <- function(configargs="") -{ - return( - paste0( - ind,'\t"build-commands": [ "R CMD INSTALL .', ifelse(configargs == "", "", paste0(" --configure-args=",configargs)) ,'" ]\n',ind,'}', - sep='', - collapse='' - ) - ); -} - -ind <- '\t\t' - -convertToJsonGitBuild <- function(pkgName) -{ - repo <- paste0('https://github.com/', specials[[pkgName]]$repo) - commit <- specials[[pkgName]]$commit - - return(paste0( - ind,'{\n',ind,'\t"name": "', - pkgName, - '",\n',ind,'\t"buildsystem": "simple",\n',ind,'\t"sources": [\n',ind,'\t\t{\n',ind,'\t\t\t"type": "git",\n',ind,'\t\t\t"url": "', - repo, - '",\n',ind,'\t\t\t"commit": "', - commit, - '"\n',ind,'\t\t}\n',ind,'\t],\n', - generateRCmdInstall(), - sep='', - collapse='')) -} - -convertToJsonDefault <- function(pkgName) -{ - needsJAGSInfo = (pkgName == "runjags"); #rjags is smart enough, but runjags isnt... - - pkgUrl <- downloaded[[pkgName]]$downloadUrl - pkgSha <- downloaded[[pkgName]]$sha256 - - return( - paste0( - ind,'{\n',ind,'\t"name": "', - pkgName, - '",\n',ind,'\t"buildsystem": "simple",\n',ind,'\t"sources": [\n',ind,'\t\t{\n',ind,'\t\t\t"type": "archive",\n',ind,'\t\t\t"url": "', - pkgUrl, - '",\n',ind,'\t\t\t"sha256": "', - pkgSha, - '"\n',ind,'\t\t}\n',ind,'\t],\n', - generateRCmdInstall(ifelse(needsJAGSInfo, "'--with-jags-include=/app/include/JAGS --with-jags-lib=/app/lib/'" , '')), - sep='', - collapse='' - ) - ) -} - -convertToJsonEntry <- function(pkgName) -{ - # check if something special should be done for this package - if(!exists(pkgName, where=specials, inherits=FALSE)) - return(convertToJsonDefault(pkgName)) - - switch(specials[[pkgName]]$type, - github = return(convertToJsonGitBuild(pkgName)) - ) - - stop(paste0("Found a special for pkg '", pkgName, "' that I cannot handle because type is: '", specials[[pkgName]]$type, "'")) -} - -createFlatpakJson <- function() -{ - orderedPkgs <- giveOrderedDependencies() - - jsonLines <- c('{\n\t"name": "RPackages",\n\t"buildsystem": "simple",\n\t"build-commands": [],\n\t"modules":\n\t[', paste0(as.character(lapply(orderedPkgs, convertToJsonEntry)), collapse=",\n"), '\n\t]\n}\n') - jsonFile <- "RPackages.json" - - fileConn <- file(jsonFile) - writeLines(jsonLines, fileConn) - close(fileConn) - - cat(paste0("Expected packages are written as json to ", jsonFile, " and org.jaspstats.JASP.json knows where to look for it.\n")) -} - -getInstalledPackageEnv <- function() -{ - installed <- as.data.frame(installed.packages(lib.loc = .libPaths()[1])[,c(1,3:4)]); - rownames(installed) <- NULL - installed <- installed[is.na(installed$Priority),1:2,drop=FALSE] - installEnv <- new.env(hash = TRUE, parent = parent.frame(), size=length(installed)) - - i <- 1L - while(i <= nrow(installed)) - { - pkg <- as.character(installed$Package[[i]]) - ver <- as.character(installed$Version[[i]]) - installEnv[[pkg]] <- ver - i <- i + 1L - } - - return(installEnv) -} - -installRequiredPackages <- function(stopOnError = TRUE) -{ - orderedPkgs <- giveOrderedDependencies() - installedPkgs <- getInstalledPackageEnv() - errorPkgs <- c() - - - error <- NULL - for (pkgName in orderedPkgs) - { - - version <- expEnv[[pkgName]] - isThere <- exists(pkgName, where=installedPkgs, inherits=FALSE) - - if(isThere) - isThere <- (installedPkgs[[pkgName]] == version) - - cat(paste0('Getting ready to install ',pkgName,' ',version, '\n')) - - if(isThere) - cat('Already installed!\n') - else if(exists(pkgName, where=specials, inherits=FALSE)) - { - specialDef <- specials[[pkgName]] - if(specialDef$type == 'github') - error <- try(remotes::install_github(paste0(specialDef$repo, '@', specialDef$commit))) - else - stop(paste0("Found a special that I cannot handle! (",specialDef,")")) - } - else - error <- try(remotes::install_version(package=pkgName, version=version, repos=CRAN, dependencies=FALSE, upgrade_dependencies=FALSE)) - - if (inherits(error, "try-error")) - { - if(stopOnError) stop(error) - else errorPkgs <- c(errorPkgs, pkgName) - } - - } - - - cat('All packages installed!\n') - - if(!stopOnError && length(errorPkgs) > 0) - cat("Installing the following pkgs failed: ", paste(errorPkgs, sep=", ", collapse=", "), "\n") -} - -cat('Run createFlatpakJson() to transform the expected packages of JASP into a fresh org.jaspstats.JASP.json for flatpak.\nOr run installRequiredPackages() as administrator to get you local installed version of R up to speed with the same packages.\n') diff --git a/Tools/flatpak/org.jaspstats.JASP.appdata.xml b/Tools/flatpak/org.jaspstats.JASP.appdata.xml index 588999eade..35b295d5a7 100644 --- a/Tools/flatpak/org.jaspstats.JASP.appdata.xml +++ b/Tools/flatpak/org.jaspstats.JASP.appdata.xml @@ -4,7 +4,7 @@ org.jaspstats.JASP org.jaspstats.JASP.desktop JASP - Standard statistical analyses, both classical and Bayesian + Classical and Bayesian Statistics CC0-1.0 AGPL-3.0+ @@ -26,13 +26,17 @@ - Shows the dataviewer of JASP flanked with the options and output for the Independent Samples T-Test - https://raw.githubusercontent.com/jasp-stats/jasp-desktop/development/Tools/flatpak/JASP-screenshot-0.png + Shows JASP Descriptives + https://raw.githubusercontent.com/jasp-stats/jasp-desktop/lockfiletesting/Tools/flatpak/flatpak_screenshot_0_small.png http://www.jasp-stats.org https://github.com/jasp-stats/jasp-issues/issues https://jasp-stats.org/donate/ + + #14a1e3 + #14a1e3 + diff --git a/Tools/flatpak/org.jaspstats.JASP.json b/Tools/flatpak/org.jaspstats.JASP.json deleted file mode 100644 index 80d76a591f..0000000000 --- a/Tools/flatpak/org.jaspstats.JASP.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "app-id": "org.jaspstats.JASP", - "runtime": "org.kde.Platform", - "runtime-version": "5.15", - "sdk": "org.kde.Sdk", - "base": "io.qt.qtwebengine.BaseApp", - "base-version": "5.15", - "command": "org.jaspstats.JASP", - "finish-args": [ - "--socket=x11", - "--socket=wayland", - "--share=ipc", - "--share=network", - "--filesystem=home", - "--device=dri" - ], - "build-options": { - "cxxflags": "-O2 -g -Wno-error", - "cflags": "-Wno-error", - "ldflags": "-lgfortran", - "append-ld-library-path": "/app/lib64/R/lib", - "env": { - - "CXX11": "g++", - "CXX14": "g++", - "CXX11FLAGS": "-std=gnu++11", - "CXX14FLAGS": "-std=gnu++14", - - "JASP_R_REPOSITORY": "file:///app/lib64/local-cran", - "GITHUB_PAT_DEF": "Z2hwX0M3YnZhaEJIYjF5QVVxN0p5NmtjTXhpcWRveXIyOTEwOXc4Rwo", - "GITHUB_PAT": "Z2hwX1FVQmt2dWk0WFV5SWJrN0VKc2JUWWVnTzFaVnQxbzROWmxwdwo", - - "GIT_DISCOVERY_ACROSS_FILESYSTEM": "true", - - "PREFIX": "/app", - "R_HOME": "/app/lib64/R/", - - "QMAKEPATH": "/app/lib" - } - }, - "cleanup": [ - "/include" - ], - "modules":[ - { - "name": "boost", - "buildsystem": "simple", - "build-commands":[ - "./bootstrap.sh --with-libraries=filesystem,system", - "./b2 -j${FLATPAK_BUILDER_N_JOBS} install --prefix=/app" - ], - "sources":[ - { - "type": "archive", - "url": "https://boostorg.jfrog.io/artifactory/main/release/1.71.0/source/boost_1_71_0.tar.gz", - "sha256": "96b34f7468f26a141f6020efb813f1a2f3dfb9797ecf76a7d7cbd843cc95f5bd" - } - ] - }, - { - "name": "r", - "config-opts": ["--enable-R-shlib", "--disable-BLAS-shlib"], - "build-options": { - "env": { - "CXX11": "g++", - "CXX14": "g++", - "CXX11FLAGS": "-std=gnu++11", - "CXX14FLAGS": "-std=gnu++14" - } - }, - "sources": [ - { - "type": "archive", - "url": "http://cran.r-project.org/src/base/R-4/R-4.1.0.tar.gz", - "sha256": "e8e68959d7282ca147360fc9644ada9bd161bab781bab14d33b8999a95182781" - } - ] - }, - { - "name": "LAPACK", - "buildsystem": "cmake", - "builddir": true, - "sources": [ - { - "type": "git", - "tag": "v3.8.0", - "url": "https://github.com/Reference-LAPACK/lapack" - } ] - }, - { - "name": "JAGS", - "sources": [ - { - "type": "archive", - "sha256": "8ac5dd57982bfd7d5f0ee384499d62f3e0bb35b5f1660feb368545f1186371fc", - "url": "https://static.jasp-stats.org/RPkgs/JAGS-4.3.0.tar.gz" - } ] - }, - "RPackages.json", - { - "name": "readstat", - "sources": [ - { - "type": "git", - "tag": "v1.1.0", - "url": "https://github.com/WizardMac/ReadStat" - } ] - }, - { - "name": "jasp", - "buildsystem": "qmake", - "config-opts": [ - "QMAKE_INCDIR+=/app/include/QtWebEngine" - ], - "sources": - [ - { - "type": "git", - "commit": "0046fa53f209a50577f25b439be74994844f2bff", - "url": "https://github.com/vandenman/jasp-desktop" - } - ] - } - ] -} diff --git a/Tools/flatpak/org.jaspstats.JASP.svg b/Tools/flatpak/org.jaspstats.JASP.svg index 0a3de2ccdf..d55f2f1a8d 100644 --- a/Tools/flatpak/org.jaspstats.JASP.svg +++ b/Tools/flatpak/org.jaspstats.JASP.svg @@ -1,16 +1,37 @@ image/svg+xml \ No newline at end of file + d="m 0,0 c 0.671,-0.957 0.928,-2.113 0.724,-3.261 -0.372,-2.096 -2.177,-3.617 -4.29,-3.617 -0.265,0 -0.531,0.025 -0.771,0.066 -0.82,0.148 -1.578,0.528 -2.271,1.166 l -0.079,0.062 c -0.182,0.184 -0.338,0.371 -0.465,0.556 -0.403,0.585 -0.654,1.271 -0.744,2 -0.053,0.537 -0.048,0.922 0.041,1.351 l 0.06,0.211 c 0.399,1.641 1.667,2.874 3.306,3.22 0.669,0.142 1.195,0.123 1.666,0.048 0.996,-0.18 1.885,-0.703 2.536,-1.473 C -0.217,0.238 -0.14,0.152 0,0 m -3.516,1.926 c -2.46,0 -4.454,-1.994 -4.454,-4.454 0,-2.459 1.994,-4.453 4.454,-4.453 2.459,0 4.453,1.994 4.453,4.453 0,2.46 -1.994,4.454 -4.453,4.454" /> diff --git a/Tools/flatpak/setup-rpkgs/.Rprofile b/Tools/flatpak/setup-rpkgs/.Rprofile deleted file mode 100644 index 81b960f5c6..0000000000 --- a/Tools/flatpak/setup-rpkgs/.Rprofile +++ /dev/null @@ -1 +0,0 @@ -source("renv/activate.R") diff --git a/Tools/flatpak/setup-rpkgs/.gitignore b/Tools/flatpak/setup-rpkgs/.gitignore deleted file mode 100644 index 3ea2c4bd5a..0000000000 --- a/Tools/flatpak/setup-rpkgs/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.Rproj.user/ -flatpak_folder/ -archives/ -app/ -other_deps/ diff --git a/Tools/flatpak/setup-rpkgs/R/Rprofile.R b/Tools/flatpak/setup-rpkgs/R/Rprofile.R deleted file mode 100644 index c38f390628..0000000000 --- a/Tools/flatpak/setup-rpkgs/R/Rprofile.R +++ /dev/null @@ -1,38 +0,0 @@ - -.lib64 <- if (dir.exists("/app")) { - file.path("file:", "app", "lib64") - cat("/app exists!\n") - "/app/lib64" -} else { - file.path("file:", normalizePath("flatpak_folder/flatpak-helper/local-github")) - cat("/app does not exist!\n") - "app/lib64" -} - -stripUrl <- function(url) { - gsub("/+", "_", strsplit(url, "repos/", fixed = TRUE)[[1L]][2]) -} - -download_override_flatpak <- function(url, destfile, mode = "wb", quiet = FALSE, headers = NULL) { - - options("renv.download.override" = NULL) - on.exit(options("renv.download.override" = download_override_flatpak)) - - type <- get("type", parent.frame(1)) - if (identical(type, "github")) { - cat("old url:", url, '\n') - url <- file.path(.lib64, "local-github", stripUrl(url)) - cat("new url:", url, '\n') - } - - renv:::download(url, destfile, type = type, quiet = quiet, headers = headers) - -} - -# this will only take effect AFTER flatpakRegenerateRenvStructure.R was run -if (dir.exists(file.path(.lib64, "local-github"))) { - cat("overriding renv download function\n") - options("renv.download.override" = download_override_flatpak) -} else { - cat("not overriding renv download function\n") -} diff --git a/Tools/flatpak/setup-rpkgs/R/flatpakGeneratePkgsList.R b/Tools/flatpak/setup-rpkgs/R/flatpakGeneratePkgsList.R deleted file mode 100644 index 33ec0eeb3f..0000000000 --- a/Tools/flatpak/setup-rpkgs/R/flatpakGeneratePkgsList.R +++ /dev/null @@ -1,99 +0,0 @@ -# Since everybody has a different setup, it might be that you need to adjust some (minor) things -# when running this on a new PC. The things you may need to adjust can be found by searching for -# the comment `| HERE |`. -# -# Some other remarks: -# -# - you MUST set a GITHUB_PAT, otherwise you'll get an error. Do not commit that to this file because then GitHub will invalidate it. -# - you can call this from cmd via Rscript R/flatpakGeneratePkgsList.R. (in Tools/flatpak/setup-rpkgs) - -# TODO: -# -# - look at https://github.com/andrie/miniCRAN/issues/50#issuecomment-374624319 -# it would be nice to be able to outsource this to miniCRAN which has a method for adding local pkgs to a repository -# the only downside is that it looks like miniCRAN is not actively maintained anymore. -# -# - there is some rudimentary support for caching downloaded CRAN pkgs. -# this should be extended to GitHub packages as well, but it doesn't work because I delete all old files related to a particular -# github pkg if renv alreadyd downloaded it. So now we're downloading jaspBase 20 times. - -expectedDirs <- c("R", "renv") -if (!all(expectedDirs %in% list.dirs(getwd(), recursive = FALSE, full.names = FALSE))) - stop("Incorrect working directory! Expected these directories at the top level: ", paste(expectedDirs, collapse = ", ")) - -# | HERE | you may want to adjust the paths when running this file on a new computer -jaspDir <- normalizePath(file.path(getwd(), "..", "..", "..")) # local clone of https://github.com/jasp-stats/jasp-desktop -flatpakDir <- normalizePath(file.path(jaspDir, "..", "org.jaspstats.JASP")) # local clone of https://github.com/flathub/org.jaspstats.JASP - -renvProject <- file.path(jaspDir, "Tools", "flatpak", "setup-rpkgs") -if (!identical(renv::project(), renvProject)) - renv::activate(renvProject) - -if (!identical(renv::project(), renvProject)) - stop("Failed to set renv project") - -source(file.path("R", "functions.R")) -source(file.path("R", "validators.R")) - -validateSetup(jaspDir, flatpakDir) - -guardForNonStandardPackagesInSystemLibrary() - -options(repos = list(repos = c(CRAN = "https://cran.rstudio.com"))) -# for binary packages, but this does not yet work well -# options(repos = list(repos = c(RSPM = "https://packagemanager.rstudio.com/all/__linux__/focal/latest"))) -# options("binaryPkgs" = TRUE) - -# NOTE: if you change the flatpak_dir anywhere you must also change it in the flatpak builder script! -dirs <- setupJaspDirs("flatpak_folder") - -Sys.setenv("RENV_PATHS_CACHE" = dirs["renv-cache"]) -Sys.setenv("RENV_PATHS_ROOT" = dirs["renv-root"]) - -# this version uses the default branch of all modules -- always the latest version -# jaspModules <- paste0("jasp-stats/", Filter(function(x) startsWith(x, "jasp"), dir(file.path(jaspDir, "Modules")))) - -# this version uses the local checked-out versions -- but modules that are dependencies are still retrieved from github -isJaspModule <- function(path) file.exists(file.path(path, "DESCRIPTION")) && file.exists(file.path(path, "inst", "Description.qml")) -jaspModules <- Filter(isJaspModule, list.dirs(file.path(jaspDir, "Modules"), recursive = FALSE)) -names(jaspModules) <- basename(jaspModules) - -# | HERE | you can add modules to exclude -#jaspModules <- jaspModules[setdiff(names(jaspModules), c("jaspProcessControl"))] - -# useful to find out why some function is not downloaded -# trace(renv:::renv_retrieve_impl, quote(if(package == "Rcpp") browser())) - -getModuleEnvironments(jaspModules) -# system("beep_finished.sh") - -moveMissingTarBalls(dirs) - -installRecommendedPackages(dirs) - -cleanupBigPackages(dirs) - -updateV8Rpackage(dirs) - -createLocalPackageRepository(dirs) - -# Test if multiple versions are present -# pkgs <- list.files(file.path(dirs["local-cran"], "src", "contrib"), pattern = "\\.tar\\.gz$") -# tb <- table(sapply(strsplit(pkgs, "_", fixed = TRUE), `[`, 1)) -# all(tb == 1) -# tb[tb != 1] # these packages appear more than once - -downloadV8ifneeded() -copyV8Lib(dirs) -copyRfiles(dirs) - -validateFlatpakFolder(dirs) - -# debugonce(createTarArchive) -info <- createTarArchive(dirs, jaspDir, verbose = FALSE, compression = "best") - -# | HERE | you may wish to flip the local flag to adjust the script so it uses the local archive -writeRpkgsJson(file.path(flatpakDir, "RPackages.json"), info, local = FALSE) - -# IF you have ssh setup this will upload the tar.gz to static-jasp. It's nicer to do this via a terminal because there you see a progress bar -uploadTarArchive(info["tar-file"], printOnly = TRUE) diff --git a/Tools/flatpak/setup-rpkgs/R/flatpakRegenerateRenvStructure.R b/Tools/flatpak/setup-rpkgs/R/flatpakRegenerateRenvStructure.R deleted file mode 100644 index e1e44d1085..0000000000 --- a/Tools/flatpak/setup-rpkgs/R/flatpakRegenerateRenvStructure.R +++ /dev/null @@ -1,77 +0,0 @@ -# To run this locally, first run flatpakGeneratePkgsList.R and then do: -# next, do: -# setwd("flatpak_folder") - - -helperfile <- list.files(pattern = "functions\\.R", full.names = TRUE, recursive = TRUE) -source(helperfile) -# source("flatpak-helper/r-helpers/functions.R") - -prettyCat(getwd()) -prettyCat(dir(getwd())) -prettyCat(.libPaths()) - -# these directories point to everything in the zip file -dirs <- setupJaspDirs(clearAll = FALSE) -prettyCat(dirs) - -# if you're running this locally, we pretend /app is just app so the code can be run -runningLocally <- !dir.exists("/app") -dirApp <- if (runningLocally) "app" else "/app" -dirLib64 <- file.path(dirApp, "lib64") -flatpakDirs <- setupJaspDirs(dirLib64, jaspSubdir = "", clearAll = FALSE, renvOnly = TRUE) - -prettyCat(dirApp) -prettyCat(dirLib64) -prettyCat(flatpakDirs) - -Sys.setenv("RENV_PATHS_CACHE" = flatpakDirs["renv-cache"]) -Sys.setenv("RENV_PATHS_ROOT" = flatpakDirs["renv-root"]) - -options("repos" = c("local" = file.path("file:", dirs["local-cran"]))) -options(install.opts = "--no-html") -options(renv.cache.linkable = TRUE) -# options(renv.config.install.verbose = TRUE) - -# uncomment to test locally (and not pollute renv/library) -# .libPaths(c(tempdir(), .libPaths())) - -# remotes is called through loadNamespace somewhere although we no longer need/ use it... -install.packages(c("renv", "remotes")) - -# V8 needs to be present after installing as well -file.copy(from = file.path(dirs["other-dependencies"], "v8"), to = dirLib64, recursive = TRUE) - -dirV8 <- file.path(dirLib64, "v8") -# This must be an absolute path, since installation is staged -if (runningLocally) dirV8 <- normalizePath(dirV8) - -prettyCat(dir()) -prettyCat(dir(dirApp)) - -dirLibGit2 <- file.path(dirApp, "libgit2") -configureVars <- c( - V8 = sprintf("INCLUDE_DIR=%1$s/include LIB_DIR=%1$s/lib", dirV8), - gert = sprintf("INCLUDE_DIR=%1$s/include LIB_DIR=%1$s", dirLibGit2) -) -options(configure.vars = configureVars) -prettyCat(configureVars) - -# set environment variable for V8 -libArch <- system("uname -m", intern = TRUE) -Sys.setenv("LIB_ARCH" = if (identical(libArch, "x86_64")) "x64" else "aarch64") -prettyCat(Sys.getenv("LIB_ARCH")) - -# install V8 and gert here so later they only need to be retrieved from the cache -availablePkgs <- available.packages() -toInstall <- intersect(c("V8", "gert"), availablePkgs[, "Package"]) -renv::install(toInstall) -renv::install('MatrixModels') - -# installJaspStats(c("jaspBase", "jaspGraphs"), dirs) - -prettyCat(setNames(lapply(.libPaths(), dir), .libPaths())) - -file.copy(from = dirs["local-cran"], to = dirLib64, recursive = TRUE) -file.copy(from = dirs["local-github"], to = dirLib64, recursive = TRUE) -file.copy(from = file.path(dirs["r-helpers"], "Rprofile.R"), to = dirLib64) diff --git a/Tools/flatpak/setup-rpkgs/R/functions.R b/Tools/flatpak/setup-rpkgs/R/functions.R deleted file mode 100644 index 64e61d714d..0000000000 --- a/Tools/flatpak/setup-rpkgs/R/functions.R +++ /dev/null @@ -1,893 +0,0 @@ -assignFunctionInPackage <- function(fun, name, package) { - # copied from jaspBase - ns <- getNamespace(package) - unlockBinding(name, ns) - assign(name, fun, ns) - lockBinding(name, ns) -} - -packageFromUrl <- function(url) { - split <- strsplit(url, "/")[[1]] - if (grepl("github", url, fixed = TRUE)) { - idx <- which(split == "tarball")[1L] - return(split[idx - 1]) - } else { - return(split[length(split) - 1]) - } -} - -stopEarlyExit <- function(message = "expected error: early exit", call = NULL, ...) { - err <- structure( - list( - message = message, - call = call, - ... - ), - class = c("earlyExit", "condition") - ) - stop(err) -} - -download_override <- function(url, destfile, mode = "wb", quiet = FALSE, headers = NULL) { - - # TODO: - # tweak this so that previously downloaded packages are not downloaded again - # just make an environment with recorded urls + local file locations - # right now, jaspBase + jaspGraphs are redownloaded for every module... - - # this allows us to just use the standard renv construction for installing stuff - tryCatch({ - options("renv.download.override" = NULL) - on.exit(options("renv.download.override" = download_override)) - - # a little bit hacky, but without the correct type the GITHUB_PAT is not used (and we really want that to be used) - type <- get("type", parent.frame(1)) - - dirs <- getDirs() - - if (!is.null(type)) { - if (type == "repository") { - - # check if this pkg has been downloaded before - pkg <- basename(url) - if (pkg != "PACKAGES.rds") { - pkgName <- gsub("_.*", "", pkg) - - localFile0 <- file.path(dirs["local-cran-source"], pkg) - if (getOption("binaryPkgs", FALSE)) { - localFile1 <- file.path(dirs["renv-root-binary"], pkgName, pkg) - } else { - localFile1 <- file.path(dirs["renv-root-source"], pkgName, pkg) - } - - if (file.exists(localFile1)) { - - ws <- strrep(" ", 35 - nchar(pkg)) # NetworkComparisonTest is the longest package name I encountered - maybecat(sprintf("Already downloaded %s%sreusing %s\n", pkg, ws, makePathRelative(localFile1, dirs["jasp-subdir"]))) - if (!file.exists(localFile0)) - file.copy(from = localFile1, to = localFile0) - return(localFile1) - } - } - } else if (type == "github") { - - if (grepl("/tarball/.+$", url)) { - - pieces <- strsplit(url, "/", TRUE)[[1]] - pkgName <- pieces[6] - SHA <- pieces[8] - - localFile0 <- file.path(dirs["local-github"], stripUrl(url)) - localFile1 <- file.path(dirs["renv-root"], "source", "github", pkgName, paste0(pkgName, "_", SHA, ".tar.gz")) - if (file.exists(localFile1)) { - ws <- strrep(" ", 35 - nchar(pkgName)) # NetworkComparisonTest is the longest package name I encountered - maybecat(sprintf("Already downloaded %s%sreusing %s\n", pkgName, ws, makePathRelative(localFile1, dirs["jasp-subdir"]))) - if (!file.exists(localFile0)) - file.copy(from = localFile1, to = localFile0) - return(localFile1) - } - } - } - } - - file <- renv:::download(url, destfile, type = type, quiet = quiet, headers = headers) - if (!identical(type, "github")) { - maybecat(sprintf("skipping url: %s\n", url)) - } else { - - to <- file.path(dirs["local-github"], stripUrl(url)) - maybecat(sprintf("recording github url: %s to %s\n", makeGitHubUrlRelative(url), makePathRelative(to))) - if (file.exists(to)) { - maybecat(sprintf("%s already exists, deleting older versions!\n", makePathRelative(to))) - existingFiles <- list.files(path = dirname(to), pattern = paste(basename(to), "*"), full.names = TRUE) - res <- file.remove(existingFiles) - if (!all(res)) - stop2("Failed to remove previously downloaded GitHub packages: ", paste(existingFiles[!res], collapse = ", ")) - } - file.copy(from = destfile, to = to, overwrite = TRUE) - - } - - # renv does need this, but we don't - if (endsWith(url, "PACKAGES.rds") || endsWith(destfile, ".json") || startsWith(basename(destfile), "renv-")) { - return(file) - } - maybecat(sprintf("recording package url: %s\n", url)) - - storeUrl(url, destfile) - - return(file) - - }, error = function(e) { - if (interactive()) - browser() - else - stop2(e) - } - ) - -} - -maybecat <- function(x) { - if (getResultsEnv()$debug) cat(x) -} - -getResultsEnv <- function() get("resultsEnv", envir = .GlobalEnv) - -createResultsEnv <- function(dirForPkgs, downloadPkgs, fromLockFile = FALSE, debug = TRUE) { - if (exists("resultsEnv", envir = .GlobalEnv)) - rm(list = "resultsEnv", envir = .GlobalEnv) - assign("resultsEnv", new.env(parent = .GlobalEnv), pos = .GlobalEnv) - resultsEnv <- getResultsEnv() - resultsEnv$index <- 1L - resultsEnv$dirForPkgs <- dirForPkgs - resultsEnv$downloadPkgs <- downloadPkgs - resultsEnv$fromLockFile <- fromLockFile - resultsEnv$debug <- debug - - # if (!downloadPkgs && !fromLockFile) { - # fakepkgpath <- file.path(tempdir(), "fakepkg") - # mkdir(fakepkgpath) - # - # if (!file.exists(file.path(fakepkgpath, "fakepkg"))) - # utils::package.skeleton(name = "fakepkg", path = fakepkgpath) - # - # fakepkgtar <- file.path(tempdir(), "fakepkgtar.tar.gz") - # if (!file.exists(fakepkgtar)) { - # oldwd <- getwd() - # on.exit(setwd(oldwd), add = TRUE) - # setwd(file.path(fakepkgpath)) - # tar(fakepkgtar, list.files(), compression = "gzip", tar = "tar") - # } - # resultsEnv$fakepkgtar <- fakepkgtar - # } - - - resultsEnv -} - -storeUrl <- function(url, destfile) { - resultsEnv <- getResultsEnv() - # destfile <- file.path(resultsEnv$dirForPkgs, basename(destfile)) - - i <- resultsEnv$index - - resultsEnv$url[i] <- url - resultsEnv$destfile[i] <- destfile - resultsEnv$index <- resultsEnv$index + 1 -} - -stripUrl <- function(url) { - # since repos is hardcoded in renv:::renv_remotes_resolve_github_ref_impl and we modify host, - # this looks like the safest approach - gsub("/+", "_", strsplit(url, "repos/", fixed = TRUE)[[1L]][2]) -} - -mkdir <- function(x, deleteIfExists = FALSE) { - if (deleteIfExists) { - if (dir.exists(x)) - unlink(x, recursive = TRUE) - dir.create(x, recursive = TRUE) - } else if (!dir.exists(x)) { - dir.create(x, recursive = TRUE) - } -} - -hasRenvLockFile <- function(modulePkg) { - return(file.exists(file.path(modulePkg, "renv.lock"))) -} - -postProcessResults <- function() { - - resultsEnv <- getResultsEnv() - resultsEnv$packages <- character(length(resultsEnv$url)) - resultsEnv$version <- character(length(resultsEnv$url)) - - idx_cran <- grep("src/contrib/", resultsEnv$url) - if (length(resultsEnv$url) > 0L) { - temp <- strsplit(basename(resultsEnv$url[idx_cran]), "_", fixed = TRUE) - - resultsEnv$packages[idx_cran] <- vapply(temp, `[`, character(1L), 1L) - resultsEnv$version [idx_cran] <- sub(".tar.gz$", "", vapply(temp, `[`, character(1L), 2L)) - resultsEnv$source [idx_cran] <- "repository" - - idx_github <- grep("api.github.com/", resultsEnv$url) - - resultsEnv$packages[idx_github] <- gsub(".*/(.+)/tarball/.*", "\\1", resultsEnv$url[idx_github]) - resultsEnv$version [idx_github] <- basename(resultsEnv$url[idx_github]) # actually just the commit - resultsEnv$source [idx_github] <- "github" - } - - for (i in seq_along(resultsEnv$records)) - if (isGitHubRecord(resultsEnv$records[[i]])) - resultsEnv$records[[i]]$Path <- makePathRelative(resultsEnv$records[[i]]$Path) - - return(resultsEnv) -} - -makePathRelative <- function(path, base = getwd(), prepend = TRUE) { - if (prepend) base <- paste0(base, .Platform$file.sep) - gsub(pattern = base, replacement = "", x = path, fixed = TRUE) -} - -makeGitHubUrlRelative <- function(url) { - makePathRelative(url, "https://api.github.com/", FALSE) -} - -getFlatpakJSONFromDESCRIPTION <- function(pathToModule, dirForPkgs = tempdir(), downloadPkgs = FALSE) { - - if (!downloadPkgs) - warning("with downloadPkgs = FALSE dependencies of DEPENDENCIES won't show up in the results!", immediate. = TRUE) - - library <- file.path(dirForPkgs, "library") - mkdir(library) - resultsEnv <- createResultsEnv(dirForPkgs, downloadPkgs) - resultsEnv$records <- customRenvInstall(packages = pathToModule, library = library, rebuild = TRUE) - -} - -guardForNonStandardPackagesInSystemLibrary <- function() { - # look for packages in the system library and tell renv to rebuild them so it doesn't try to reuse them - installed <- installed.packages(.libPaths()[-1L]) - idx <- !startsWith(installed[, "License"], "Part of R ") - badPackagesFoundInSystemLibrary <- installed[idx, "Package"] - if (length(badPackagesFoundInSystemLibrary) > 0L) { - cat("Warning: The following packages were found in the system library but they are not shipped with R!\nThis script should still work, but you probably don't want this.\n") - cat(badPackagesFoundInSystemLibrary, sep = ", ") - cat("\n") - } - options(badPackagesFoundInSystemLibrary = badPackagesFoundInSystemLibrary) -} - -customRenvInstall <- function(packages, library = NULL, rebuild = TRUE, customDownload = TRUE) { - - if (customDownload) { - options("renv.download.override" = download_override) - on.exit(options("renv.download.override" = NULL)) - } - - old_renv_impl_install <- renv:::renv_install_impl - on.exit(assignFunctionInPackage(old_renv_impl_install, "renv_install_impl", "renv"), add = TRUE) - assignFunctionInPackage(identity, "renv_install_impl", "renv") - - rebuild <- c(packages, getOption("badPackagesFoundInSystemLibrary", default = character())) - renv::install(packages = packages, library = library, rebuild = rebuild) - -} - -installRecommendedPackages <- function(dirs) { - - installed <- installed.packages(.libPaths()) - recPkgs <- unname(installed[installed[, "Priority"] %in% "recommended", "Package"]) - - alreadyDownloadedPkgs <- list.files(dirs["local-cran-source"], pattern = "\\.tar\\.gz$", recursive = TRUE, full.names = FALSE) - alreadyDownloadedPkgs <- gsub("_(.*)", "", basename(alreadyDownloadedPkgs)) - - toInstall <- c(recPkgs, - # for some reason, "devtools" and "roxygen2" are missing... - # renv is not a direct dependency and is installed by default - # jasp-desktop does somewhere loadNamespace("remotes"), which is why we also download it here - "devtools", "roxygen2", "renv", "remotes" - ) - - toInstall <- setdiff(toInstall, alreadyDownloadedPkgs) - - # these must be installed from CRAN - options(repos = list(repos = c(CRAN = "https://cran.rstudio.com"))) - if (length(toInstall) > 0L) { - cat("Downloading recommended packages:", paste(toInstall, collapse = ", ")) - customRenvInstall(toInstall, customDownload = FALSE) - } else { - cat("All recommended packages are downloaded.") - } - -} - -# getFlatpakJSONFromLockfile <- function(pathToModule, dirForPkgs = tempdir(), downloadPkgs = FALSE) { -# -# options("renv.download.override" = download_override) -# on.exit(options("renv.download.override" = NULL)) -# -# lockfile <- jsonlite::fromJSON(file.path(pathToModule, "renv.lock")) -# records <- lockfile$Packages -# records <- Filter(function(x) !x$Package %in% c("jaspTools", "jaspResults"), records) -# -# nrecords <- length(records) -# -# resultsEnv <- createResultsEnv(dirForPkgs, downloadPkgs, fromLockFile = TRUE) -# resultsEnv$packages <- character(nrecords) -# resultsEnv$url <- character(nrecords) -# resultsEnv$destfile <- character(nrecords) -# resultsEnv$records <- vector("list", nrecords) -# -# pb <- utils::txtProgressBar(max = nrecords, style = 3) -# on.exit(close(pb), add = TRUE) -# for (i in seq_along(records)) { -# -# # TODO: consider the same hack as in getFlatpakJSONFromDESCRIPTION to overwrite renv:::renv_install -# -# tryCatch( -# # rebuild ensures we bypass the cache -# capture.output(renv::install(records[i], rebuild = TRUE, sources = "")), -# earlyExit = function(e) {}, -# error = function(e) { -# if (!identical(e[["message"]], "failed to retrieve 'Error: expected error: early exit\n' [expected error: early exit]")) { -# browser(e) -# print(paste("got an error:", e[["message"]])) -# } -# } -# ) -# -# utils::setTxtProgressBar(pb, i) -# -# } -# -# } - -getFlatpakJSONFromModule <- function(pathToModule, dirForPkgs = tempdir(), downloadPkgs = FALSE) { - - mkdir(dirForPkgs) - - # for now we assume no modules have a lockfile - # if (hasRenvLockFile(pathToModule)) { - # getFlatpakJSONFromLockfile(pathToModule, dirForPkgs, downloadPkgs) - # } else { - getFlatpakJSONFromDESCRIPTION(pathToModule, dirForPkgs, downloadPkgs) - # } - - postProcessResults() - -} - -# repository infrastructure -createFolderStructure <- function(toplevel = file.path(getwd(), "toplevelRepository")) { - - contrib <- file.path(toplevel, "src", "contrib") - mkdir(contrib) - contribBinary <- file.path(toplevel, "bin", "linux", "contrib") - mkdir(contribBinary) - return(c("root" = toplevel, "source" = contrib, "binary" = contribBinary)) - -} - -getPackageFilesBySource <- function(resultsEnv, source, invert = FALSE) { - - idx <- if (invert) resultsEnv$source != source else resultsEnv$source == source - return(paste0(resultsEnv$packages[idx], "_", resultsEnv$version[idx], ".tar.gz")) - -} - -createLocalRepository <- function(contrib, sourcePkgsDir) { - - # nonRepositoryPkgsNames <- Reduce(unique, lapply( - # moduleEnvironments, - # function(resultsEnv) getPackageFilesBySource(resultsEnv, "repository", invert = TRUE) - # )) - - # repositoryPkgFiles <- setdiff(list.files(sourcePkgsDir, pattern = "\\.tar\\.gz$", recursive = TRUE), nonRepositoryPkgsNames) - - repositoryPkgFiles <- list.files(sourcePkgsDir, pattern = "\\.tar\\.gz$", recursive = TRUE, full.names = TRUE) - - file.copy(repositoryPkgFiles, to = file.path(contrib, basename(repositoryPkgFiles))) - tools::write_PACKAGES(contrib, type = "source") - -} - -createLocalGithubRepository <- function(resultsEnv, githubDir, sourcePkgsDir) { - - githubPkgsNames <- getPackageFilesBySource(resultsEnv, "github") - - githubRecords <- Filter(function(x) x[["Source"]] == "GitHub", resultsEnv$records) - temp <- vapply(githubRecords, function(x) paste0(x$Package, "_", x$RemoteSha, ".tar.gz"), character(1L)) - githubPkgsNames <- githubPkgsNames[match(temp, githubPkgsNames)] - - fmt <- "%s/repos/%s/%s/tarball/%s" - for (i in seq_along(githubRecords)) { - record <- githubRecords[[i]] - newPath <- file.path(githubDir, sprintf(fmt, record$RemoteUsername, record$RemoteRepo, record$RemoteSha, githubPkgsNames[i])) - mkdir(dirname(newPath)) - file.copy(file.path(sourcePkgsDir, githubPkgsNames[i]), newPath) - } - -} - -createLocalPackageRepository <- function(dirs) { - - createLocalRepository(dirs["local-cran-source"], dirs[c("renv-root-source", "renv-root-binary")]) - -} - -copy_of_renv_bootstrap_platform_prefix <- function() { - # as the name suggests, a copy of renv:::renv_bootstrap_platform_prefix - version <- paste(R.version$major, R.version$minor, sep = ".") - prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") - devel <- identical(R.version[["status"]], "Under development (unstable)") || - identical(R.version[["nickname"]], "Unsuffered Consequences") - if (devel) - prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") - components <- c(prefix, R.version$platform) - # prefix <- renv_bootstrap_platform_prefix_impl() - prefix <- NA - if (!is.na(prefix) && nzchar(prefix)) - components <- c(prefix, components) - paste(components, collapse = "/") -} - -setupJaspDirs <- function(root = getwd(), jaspSubdir = "jasp-build", flatpakSubdir = "flatpak-helper", clearAll = FALSE, renvOnly = FALSE) { - - paths <- c( - # folder structure should be identical to JASP - "Modules" = file.path(root, jaspSubdir, "Modules"), - "renv-cache" = file.path(root, jaspSubdir, "renv-cache"), - "renv-root" = file.path(root, jaspSubdir, "renv-root"), - "renv-root-source" = file.path(root, jaspSubdir, "renv-root", "source", "repository"), - "renv-root-binary" = file.path(root, jaspSubdir, "renv-root", "binary", copy_of_renv_bootstrap_platform_prefix(), "repository"), - - # these directories are only relevant for building flatpak - "module-environments" = file.path(root, flatpakSubdir, "module-environments"), - "other-dependencies" = file.path(root, flatpakSubdir, "other-dependencies"), - "r-helpers" = file.path(root, flatpakSubdir, "r-helpers"), - "local-cran" = file.path(root, flatpakSubdir, "local-cran"), - "local-cran-source" = file.path(root, flatpakSubdir, "local-cran", "src", "contrib"), - "local-cran-binary" = file.path(root, flatpakSubdir, "local-cran", "bin", "linux", "contrib"), - "local-github" = file.path(root, flatpakSubdir, "local-github"), - "root" = root, - "jasp-subdir" = file.path(root, jaspSubdir), - "flatpak-dir" = file.path(root, flatpakSubdir) - ) - - if (renvOnly) - paths <- paths[startsWith(names(paths), "renv-")] - - if (clearAll) - lapply(paths, unlink, recursive = TRUE) - - lapply(paths, mkdir) - - return(sapply(paths, normalizePath)) -} - -getModuleEnvironments <- function(jaspModules) { - # moduleEnvironments contains all meta data for the packages (versions, url, etc.) - moduleEnvironments <- setNames(vector("list", length(jaspModules)), names(jaspModules)) - - for (url in jaspModules) { - nm <- basename(url) - moduleEnvironments[[nm]] <- getFlatpakJSONFromModule(url, downloadPkgs = TRUE) - } - return(invisible(moduleEnvironments)) -} - -installGitHubRecords <- function(githubRecords, tempLib) { - - # pretend the github packages are local packages (which they are) - # the order of githubRecords follows the order of the obtained URLs so the module of interest is always last - for (temprecord in githubRecords) { - record <- list(list( - Package = temprecord[["Package"]], - Version = temprecord[["Version"]], - Path = fixLocalPath(temprecord[["Path"]]), # renv requires an absolute path - Source = "Local", - Cacheable = TRUE - )) - names(record) <- temprecord[["Package"]] - print("installing record:") - print(record) - renv::install(record, library = tempLib, project = tempLib[1]) - } - -} - -fixLocalPath <- function(path) { - - # TODO: this function is unnessecary if we'd store the correct path immediately! - # the problem is that if you modify flatpakGeneratePkgsList, this might modify the path - # and this function is a convenient fallback - - # .. I should really delete this - path <- sub(pattern = "jasp_build", replacement = "jasp-build", x = path, fixed = TRUE) - - cat("wd:\t", getwd(), "\ndir():\t", dir(getwd()), "\npath:\t", path, '\n') - cat(file.path(getwd(), path), "\n") - if (file.exists(path)) - return(normalizePath(path)) - - - print(dir(file.path(getwd(), "jasp-build", "renv-root/source/github/jaspBase/"))) - print(dir(file.path(getwd(), "jasp-build", "renv-root/source/github/"))) - print(dir(file.path(getwd(), "jasp-build", "renv-root/source/"))) - - orgpath <- path - oldpath <- path - newpath <- sub("[^/]+/", "", oldpath) - - # drop the highest directory until the thingy exists - while (oldpath != newpath) { - cat(sprintf("trying path %s\n", file.path(getwd(), newpath))) - if (file.exists(file.path(getwd(), newpath))) - return(normalizePath(file.path(getwd(), newpath))) - oldpath <- newpath - newpath <- sub("[^/]+/", "", newpath) - } - stop2(sprintf("Could not make this path work: %s", orgpath)) - -} - -isGitHubRecord <- function(x) { - x[["Source"]] == "GitHub" -} - -installModules <- function(dirs, moduleEnvironments) { - - moduleNames <- names(moduleEnvironments) - for (i in seq_along(moduleEnvironments)) { - - env <- moduleEnvironments[[i]] - githubRecords <- Filter(isGitHubRecord, env$records) - - lib <- file.path(dirs["Modules"], moduleNames[i]) - unlink(lib, recursive = TRUE) - mkdir(lib) - - # we use here the last libPaths. Usually that one only contains the default packages (e.g., when using renv) - # when this also contains other packages, the installation behavior might differ from flatpak - libpaths <- .libPaths() - installGitHubRecords(githubRecords, c(normalizePath(lib), libpaths[length(libpaths)])) - - } - -} - -downloadFile <- function(url, destdir) { - mkdir(destdir) - destfile <- file.path(destdir, basename(url)) - download.file(url = url, destfile = destfile) - return(destfile) -} - -copyRfiles <- function(dirs) { - rfiles <- list.files("R", pattern = "*\\.R$", full.names = TRUE) - successes <- file.copy(from = rfiles, to = dirs["r-helpers"], overwrite = TRUE) - if (!all(successes)) - stop2("failed to copy these R files: ", paste(rfiles[!successes], collapse = ", "), " to ", dirs["r-helpers"]) - -} - -createTarArchive <- function(dirs, jaspDir, outputPath = "archives/flatpak_archive_%s.tar.gz", compression = c("fast", "none", "best"), - verbose = TRUE, update = FALSE) { - - # TODO: update does not work - - if (grepl("%s", outputPath)) { - # get the tag of the current jasp-desktop clone or the commit hash as a fallback - commitHash <- system(sprintf("cd %s && git describe --exact-match --tags 2> /dev/null || git rev-parse HEAD", jaspDir), intern = TRUE) - outputPath <- sprintf(outputPath, commitHash) - } - - if (update && !identical(compression[1L], "none")) { - warning("can only update when compression is 'none'! Not updating instead.", immediate. = TRUE) - update <- FALSE - } - - if (!is.numeric(compression)) { - compression <- match.arg(compression) - compression <- switch(compression, - "none" = "", - "best" = "-I 'gzip -9'", - "fast" = "-I 'gzip -1'" - ) - } else if (!is.numeric(compression) || (is.numeric(compression) && !(compression >= 1 && compression <= 9))) { - stop2("compression must be character ('best' or 'fast') or numeric (1-9)") - } - - dirsForArchive <- dirs["flatpak-dir"] - # dirsForArchive <- c(dirs["flatpak-dir"], file.path(dirs["renv-root"], "source", "github")) - - # files <- file.path("..", basename(getwd()), makePathRelative(dirsForArchive)) - files <- makePathRelative(dirsForArchive, base = dirname(dirs["root"])) - - mkdir(dirname(outputPath)) - - creatArchive <- sprintf( - "tar --mode=a+rw %s -%s%sf %s %s", - compression, - if (verbose) "v" else "", - if (update) "u" else "c", - outputPath, - paste(files, collapse = " ") - ) - cat('running: ', creatArchive, '\n') - system(creatArchive) - - sha256 <- strsplit(system2("sha256sum", outputPath, stdout = TRUE), " ", fixed = TRUE)[[1]][1] - cat("\nsha256sum\n") - cat(sha256, '\n') - - rfile <- makePathRelative(file.path(dirs["r-helpers"], "flatpakRegenerateRenvStructure.R"), base = dirs["root"]) - cat(sprintf("command for flatpak\nR --vanilla --file=%s\n", rfile)) - - return(c( - "tar-file" = outputPath, - "sha256" = sha256, - "r-file" = rfile - )) -} - -uploadTarArchive <- function(archivePath = "archives/flatpak_archive.tar.gz", verbose = TRUE, printOnly = TRUE) { - - if (!file.exists(archivePath)) - stop2("Archive does not exist") - - archivePath <- normalizePath(archivePath) - archiveName <- "flatpak_archive_buildbot.tar.gz" - - cmd <- sprintf("scp %s jonathonlove@static.jasp-stats.org:static.jasp-stats.org/%s", archivePath, archiveName) - if (printOnly) cat(cmd) else system(cmd) - -} - -writeRpkgsJson <- function(path, info, local = FALSE) { - - template <- '{ - "name": "RPackages2", - "buildsystem": "simple", - "build-commands": [], - "modules": - [ - { - "name": "Rpackages", - "buildsystem": "simple", - "sources": [ - { - "type": "archive", - "url": "%s", - "sha256": "%s" - } - ], - "build-commands": ["cd ./flatpak-helper/local-cran/src/contrib && gunzip rstanarm* && tar --delete -vf rstanarm_*.tar rstanarm/cleanup && gzip rstanarm*.tar", - "R --vanilla --file=%s" ] - } - ] -} -' - - location <- if (local) { - file.path("file:/", normalizePath(info["tar-file"])) - } else { - paste0("http://static.jasp-stats.org/", "flatpak_archive_buildbot.tar.gz") - } - - new <- sprintf(template, location, info["sha256"], info["r-file"]) - writeLines(new, path) - -} - -prettyCat <- function(x) { - name <- deparse(substitute(x)) - if (is.list(x)) { - cat(name, '\n') - cat(unlist(lapply(seq_along(x), function(i) paste(c(names(x[i]), x[[i]]), collapse = "\n"))), sep = '\n\n') - } else if (!is.null(names(x))) - cat(name, '\n', paste(format(names(x)), unname(x), sep = '\t', collapse = '\n'), '\n', sep = "") - else if (length(x) == 1L) - cat(name, '\t', x, '\n', sep = "") - else - cat(name, '\n', paste(x, collapse = '\n'), '\n', sep = "") -} - -installJaspStats <- function(pkgs, dirs) { - - paths <- character(length(pkgs)) - for (i in seq_along(pkgs)) { - pathsFound <- list.files(path = dirs["local-github"], pattern = sprintf("^jasp-stats_%s_tarball_", pkgs[i]), full.names = TRUE) - if (length(pathsFound) != 1L) - stop2("There are ", if (length(pathsFound) < 1L) "zero" else "multiple", " ", pkgs[i], "_*.tar.gz present!") - paths[i] <- pathsFound - } - - prettyCat(paths) - - for (path in paths) { - pathtemp <- tempfile(fileext = ".tar.gz") - file.copy(path, to = pathtemp) - renv::install(pathtemp) - } - -} - -makeTar <- function(pathOriginal, dirTemp) { - - newPathV8 <- file.path(dirTemp, basename(pathOriginal)) - oldwd <- getwd() - on.exit(setwd(oldwd)) - setwd(dir) - tar(tarfile = newPathV8, files = "V8", compression = "gzip") - - file.copy(from = newPathV8, to = pathOriginal, overwrite = TRUE) - -} - -cleanupBigPackages <- function(dirs) { - - # So the GitHub downloads contain EVERYTHING in a repo. That's much more than we need. - # Luckily, almost every package has an .Rbuildignore. So when we unpack the github tarball - # and ask R to build a source package then anything listed in .Rbuildignore is excluded - # from the tarball. This provides a very effective way for deleting useless files while not - # having to make any guesses about what the package authors intended. - # In addition, this function deletes the folders "tests" and "vignettes". - - oldwd <- getwd() - on.exit(setwd(oldwd)) - paths <- list.files(dirs["local-github"], pattern = "*_tarball_*", full.names = TRUE) - - dirTemp <- file.path(tempdir(), "resize-github-pkgs") - mkdir(dirTemp, deleteIfExists = TRUE) - - rpath <- file.path(Sys.getenv("R_HOME"), "bin", "R") - - for (i in seq_along(paths)) { - - path <- paths[i] - dirTempPkg <- file.path(dirTemp, basename(path)) - mkdir(dirTempPkg, deleteIfExists = TRUE) - untar(path, exdir = dirTempPkg) - - newPath <- file.path(dirTempPkg, dir(dirTempPkg)) - - unlink(file.path(newPath, c( - "vignettes", - "tests" - )), recursive = TRUE) - - dirTemp2 <- file.path(tempdir(), basename(path)) - mkdir(dirTemp2, deleteIfExists = TRUE) - - if (startsWith(basename(path), "dustinfife_flexplot")) { - # flexplot removes jasp related files in the .Rbuildignore... - .RbuildignorePath <- file.path(newPath, ".Rbuildignore") - if (file.exists(.RbuildignorePath)) { - .Rbuildignore <- readLines(.RbuildignorePath) - .Rbuildignore <- .Rbuildignore[!(grepl("jasp", .Rbuildignore) & endsWith(.Rbuildignore, ".R"))] - writeLines(.Rbuildignore, .RbuildignorePath) - } - - } - - setwd(dirTemp2) - cmd <- sprintf("%s CMD build --no-build-vignettes --no-manual --resave-data %s", rpath, newPath) - system(cmd) - - file.copy(from = dir(dirTemp2), to = path, overwrite = TRUE) - - } - -} - -copyV8Lib <- function(dirs, source = "other_deps/v8") { - if (!file.copy(source, to = dirs["other-dependencies"], recursive = TRUE)) - stop2("Failed to copy from ", source, " to ", dirs["other-dependencies"]) -} - -updateV8Rpackage <- function(dirs) { - - pathV8 <- list.files(file.path(dirs["renv-root-source"], "V8"), pattern = "^V8_*", full.names = TRUE) - if (length(pathV8) == 0L) { - warning("No V8 package found. This is fine if you adjusted some things and are not building everything.", domain = NA) - return() - } - - fixV8Package <- function(pathV8) { - dirTemp <- file.path(tempdir(), "V8_fix") - mkdir(dirTemp, deleteIfExists = TRUE) - untar(tarfile = pathV8, exdir = dirTemp) - dirTempV8 <- file.path(dirTemp, "V8") - configureLines <- readLines(file.path(dirTempV8, "configure")) - configureLines[startsWith(configureLines, "PKG_LIBS=\"-lv8")] <- "PKG_LIBS=\"-lv8_monolith_$LIB_ARCH\"" - configureLines[startsWith(configureLines, "PKG_CFLAGS=\"-I/usr/include/v8")] <- "PKG_CFLAGS=\"\"" - writeLines(configureLines, file.path(dirTempV8, "configure")) - - newPathV8 <- file.path(dirTemp, basename(pathV8)) - oldwd <- getwd() - on.exit(setwd(oldwd)) - setwd(dirTemp) - tar(tarfile = newPathV8, files = "V8", compression = "gzip") - - result <- file.copy(from = newPathV8, to = pathV8, overwrite = TRUE) - if (!result) - stop2("failed to update the V8 package for path: ", pathV8) - - } - - fixV8Package(pathV8) - - # also do this for the cran repo, just in case functions are run out of order - pathV8cran <- list.files(dirs["local-cran-source"], pattern = "^V8_*", full.names = TRUE) - if (length(pathV8cran) > 0L) - fixV8Package(pathV8cran) - -} - -moveMissingTarBalls <- function(dirs) { - # sometimes renv realizes that it does not need to redownload a github package because it already has the source in - # flatpak_folder/jasp-build/renv-root/source/github. - # this function locates any missing tarballs and copies them to flatpak_folder/flatpak-helper/local-github/ - - allFiles <- list.files(dirs["local-github"]) - - r <- "^(.*)_contents_DESCRIPTION\\?ref=(.+)$" - matches <- regmatches(allFiles, regexec(r, allFiles)) - matches <- matches[lengths(matches) > 0L] - - SHAs <- unlist(lapply(matches, `[[`, 3L), use.names = FALSE) - names(SHAs) <- unlist(lapply(matches, `[[`, 2L), use.names = FALSE) - tarballs <- file.path(dirs["local-github"], paste0(names(SHAs), "_tarball_", SHAs)) - missing <- which(!file.exists(tarballs)) - - if (length(missing) > 0L) { - repoNames <- vapply(strsplit(names(SHAs[missing]), "_", fixed = TRUE), `[[`, character(1L), 2L) - backupTarballNames <- paste0(repoNames, "_", SHAs[missing], ".tar.gz") - backupTarballs <- file.path(dirs["renv-root"], "source", "github", repoNames, backupTarballNames) - - found <- file.exists(backupTarballs) - file.copy(from = backupTarballs[found], to = tarballs[missing][found]) - - cat("Moved these tarballs:\n", paste(basename(tarballs[missing][found]), collapse = ", "), "\n") - - if (any(!found)) { - warning("Did not find these tarballs: ", paste(backupTarballs[!found], collapse = ","), - " check if these tarballs are ok: ", paste(tarballs[missing][!found], collapse = ","), domain = NA) - } - } else { - cat("No missing tarballs.\n") - } -} - -downloadV8ifneeded <- function(destination = "other_deps") { - - if (!dir.exists(file.path(destination, "v8"))) { - # ensure parent folder exists - mkdir(destination) - downloadFile(url = "http://static.jasp-stats.org/v8.tar.gz", destination) - - oldwd <- getwd() - setwd(destination) - on.exit(setwd(oldwd)) - untar(tarfile = normalizePath("v8.tar.gz")) - } - -} - -getDirs <- function() { - get("dirs", envir = .GlobalEnv) -} - -stop2 <- function(..., call. = TRUE, domain = NA) { - stop(cli::col_red(cli::style_bold(paste0(..., collapse = ""))), call. = call., domain = domain) -} - -options("error" = function() { - traceback(4, max.lines = 2L) - if (!interactive()) { - quit(status = 1) - } -}) diff --git a/Tools/flatpak/setup-rpkgs/R/validators.R b/Tools/flatpak/setup-rpkgs/R/validators.R deleted file mode 100644 index a48a7887fa..0000000000 --- a/Tools/flatpak/setup-rpkgs/R/validators.R +++ /dev/null @@ -1,80 +0,0 @@ -assertDirExists <- function(x) { - if (!dir.exists(x)) - stop2("Directory ", x, " does not exist") -} - -validateJaspDir <- function(dir) { - assertDirExists(dir) - expectedDirs <- c("Common", "Desktop", "Engine", "Modules", "R-Interface", "Resources", "Tools") - if (!all(expectedDirs %in% list.dirs(dir, full.names = FALSE, recursive = FALSE))) - stop2("Invalid jaspDir. Expected these folders: ", paste(expectedDirs, collapse = ", ")) -} - -validateFlatpakDir <- function(dir) { - assertDirExists(dir) - expectedFiles <- c("flathub.json", "org.jaspstats.JASP.json", "RPackages.json") - if (!all(expectedFiles %in% list.files(dir))) - stop2("Invalid flatpakDir. Expected these files") -} - -validateGithubPath <- function() { - if (Sys.getenv("GITHUB_PAT") == "") - stop2("GITHUB_PAT is not set!") -} - -validateSetup <- function(jaspDir, flatpakDir) { - # call this before downloading pkgs - validateJaspDir(jaspDir) - validateFlatpakDir(flatpakDir) - validateGithubPath() -} - -validateGithubPkgs <- function(dirs) { - - errorMessages <- character() - allFiles <- list.files(dirs["local-github"]) - - r <- "^(.*)_contents_DESCRIPTION\\?ref=(.+)$" - matches <- regmatches(allFiles, regexec(r, allFiles)) - matches <- matches[lengths(matches) > 0L] - - SHAs <- unlist(lapply(matches, `[[`, 3L), use.names = FALSE) - names(SHAs) <- unlist(lapply(matches, `[[`, 2L), use.names = FALSE) - - # check 1: verify that all the index files match the names - this check is no good if people explicitly specify a commit in the DESCRIPTION - # indexFiles <- allFiles[grep("^([^_]*_){1}[^_]*$", allFiles)] - # diff <- setdiff(names(SHAs), indexFiles) - # if (length(diff) > 0L) - # errorMessages <- c(errorMessages, paste0("These _contents_DESCRIPTION are missing an index file: ", paste0(diff, collapse = ","))) - - # check 2: verify that every "*_contents_description*" has an associated tarball - tarballs <- file.path(dirs["local-github"], paste0(names(SHAs), "_tarball_", SHAs)) - missing <- which(!file.exists(tarballs)) - if (length(missing) > 0L) - errorMessages <- c(errorMessages, paste0("These github packages are missing a tarball: ", paste(names(SHAs)[missing], collapse = ", "))) - - if (length(errorMessages) > 0L) - stop2("These error message occurred:\n\n", paste(errorMessages, collapse = "\n")) - - return(invisible(TRUE)) - -} - -validateV8folder <- function(dirs) { - - v8Dir <- file.path(dirs["other-dependencies"], "v8") - if (!dir.exists(v8Dir)) - stop2("V8 dir does not exist at ", v8Dir, domain = NA) - - subdirs <- file.path(v8Dir, c("include", "lib", "lic")) - if (!all(dir.exists(subdirs))) - stop2("V8 dir does not contain the following subdirectories: ", paste(subdirs, collapse = ", "), domain = NA) - - -} - -validateFlatpakFolder <- function(dirs) { - # call this before creating one tar.gz - validateGithubPkgs(dirs) - validateV8folder(dirs) -} diff --git a/Tools/flatpak/setup-rpkgs/README.md b/Tools/flatpak/setup-rpkgs/README.md deleted file mode 100644 index 72b134928d..0000000000 --- a/Tools/flatpak/setup-rpkgs/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Helper functions to JASP work on flatpak - -#### Building the flatpak locally. - -From a terminal, run `Rscript R/flatpakGeneratePkgsList.R` to generate a tar.gz under archives that contains all packages. -Alternatively, open the project file in RStudio and source `flatpakGeneratePkgsList.R`. -To build JASP locally, clone https://github.com/flathub/org.jaspstats.JASP and then run `flatpak-builder --user --install --force-clean build org.jaspstats.JASP.json` where `build` is your build folder. - -#### Debugging the flatpak build - -First build the flatpak version locally. -Next, in your clone of flathub/org.jaspstats.JASP do -``` -flatpak run -d --command=sh org.jaspstats.JASP -``` -This starts shell instead of directly starting JASP. -The remainder of the commans should be run from that shell. -To start JASP with a debugger, do -``` -gdb /app/bin/org.jaspstats.JASP -``` -If you get a message about debugsymbols not found, you can hopefully locate these using: -``` -find /app/ -type f -name "*.debug" -``` diff --git a/Tools/flatpak/setup-rpkgs/TODO.md b/Tools/flatpak/setup-rpkgs/TODO.md deleted file mode 100644 index 52e2a0034b..0000000000 --- a/Tools/flatpak/setup-rpkgs/TODO.md +++ /dev/null @@ -1,26 +0,0 @@ -# TODO: - -- [x] 1. make sure the installed packages are actually symlinks -- [x] 2. make a neat interface to loop over all modules (folder structure identical to JASP!) -- [x] 3. test it for 4-5 modules -- [ ] 4. look at how multiple versions are handled within a custom CRAN repo! test if renv::install(@version) works! -- [x] 5. bundle an renv tar.gz into this and make sure we can install it separately! - -- [x] 6. look into running flatpak locally - - [x] a. how to update jasp? can look at specific commit I guess - -- [x] 7. can we do without the custom download script? No we can't -- [x] 8. make this a github repo and push it (too much work went into it already!) -- [x] 9. add renv to the local CRAN repo and install it from there! - -- [x] 10. Somehow put stuff in /app/lib64/ -- [x] 11. Don't install all the r packages, only V8, renv, and jaspBase. + jaspGraphs - -- [x] 12. Upload the big tar.gz to static. - -- [ ] 13. There are messages about "package is not available" (devtools, roxygen2, etc.) - - a. [ ] figure out if we can get these by also downloading Suggests! - -- [ ] 14. The moduleEnvironments object is no longer necessary. It's probably useful for debugging to create it but it shouldn't be in the archive. - -- [ ] 15. Reduce the size of the flatpak object (1.2 GB is a bit much). Check if unnecessary stuff is actually deleted (like local-github) diff --git a/Tools/flatpak/setup-rpkgs/renv.lock b/Tools/flatpak/setup-rpkgs/renv.lock deleted file mode 100644 index 13d0e8ffd8..0000000000 --- a/Tools/flatpak/setup-rpkgs/renv.lock +++ /dev/null @@ -1,29 +0,0 @@ -{ - "R": { - "Version": "4.2.1", - "Repositories": [ - { - "Name": "repos", - "URL": "https://cran.rstudio.com" - } - ] - }, - "Packages": { - "crayon": { - "Package": "crayon", - "Version": "1.5.1", - "Source": "Repository", - "Repository": "CRAN", - "Hash": "8dc45fd8a1ee067a92b85ef274e66d6a", - "Requirements": [] - }, - "renv": { - "Package": "renv", - "Version": "0.15.5", - "Source": "Repository", - "Repository": "CRAN", - "Hash": "6a38294e7d12f5d8e656b08c5bd8ae34", - "Requirements": [] - } - } -} diff --git a/Tools/flatpak/setup-rpkgs/renv/.gitignore b/Tools/flatpak/setup-rpkgs/renv/.gitignore deleted file mode 100644 index cb0686430c..0000000000 --- a/Tools/flatpak/setup-rpkgs/renv/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -cellar/ -library/ -local/ -lock/ -python/ -staging/ diff --git a/Tools/flatpak/setup-rpkgs/renv/activate.R b/Tools/flatpak/setup-rpkgs/renv/activate.R deleted file mode 100644 index 72c0818a82..0000000000 --- a/Tools/flatpak/setup-rpkgs/renv/activate.R +++ /dev/null @@ -1,942 +0,0 @@ - -local({ - - # the requested version of renv - version <- "0.15.5" - - # the project directory - project <- getwd() - - # figure out whether the autoloader is enabled - enabled <- local({ - - # first, check config option - override <- getOption("renv.config.autoloader.enabled") - if (!is.null(override)) - return(override) - - # next, check environment variables - # TODO: prefer using the configuration one in the future - envvars <- c( - "RENV_CONFIG_AUTOLOADER_ENABLED", - "RENV_AUTOLOADER_ENABLED", - "RENV_ACTIVATE_PROJECT" - ) - - for (envvar in envvars) { - envval <- Sys.getenv(envvar, unset = NA) - if (!is.na(envval)) - return(tolower(envval) %in% c("true", "t", "1")) - } - - # enable by default - TRUE - - }) - - if (!enabled) - return(FALSE) - - # avoid recursion - if (identical(getOption("renv.autoloader.running"), TRUE)) { - warning("ignoring recursive attempt to run renv autoloader") - return(invisible(TRUE)) - } - - # signal that we're loading renv during R startup - options(renv.autoloader.running = TRUE) - on.exit(options(renv.autoloader.running = NULL), add = TRUE) - - # signal that we've consented to use renv - options(renv.consent = TRUE) - - # load the 'utils' package eagerly -- this ensures that renv shims, which - # mask 'utils' packages, will come first on the search path - library(utils, lib.loc = .Library) - - # unload renv if it's already been loaded - if ("renv" %in% loadedNamespaces()) - unloadNamespace("renv") - - # load bootstrap tools - `%||%` <- function(x, y) { - if (is.environment(x) || length(x)) x else y - } - - bootstrap <- function(version, library) { - - # attempt to download renv - tarball <- tryCatch(renv_bootstrap_download(version), error = identity) - if (inherits(tarball, "error")) - stop("failed to download renv ", version) - - # now attempt to install - status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity) - if (inherits(status, "error")) - stop("failed to install renv ", version) - - } - - renv_bootstrap_tests_running <- function() { - getOption("renv.tests.running", default = FALSE) - } - - renv_bootstrap_repos <- function() { - - # check for repos override - repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA) - if (!is.na(repos)) - return(repos) - - # check for lockfile repositories - repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity) - if (!inherits(repos, "error") && length(repos)) - return(repos) - - # if we're testing, re-use the test repositories - if (renv_bootstrap_tests_running()) - return(getOption("renv.tests.repos")) - - # retrieve current repos - repos <- getOption("repos") - - # ensure @CRAN@ entries are resolved - repos[repos == "@CRAN@"] <- getOption( - "renv.repos.cran", - "https://cloud.r-project.org" - ) - - # add in renv.bootstrap.repos if set - default <- c(FALLBACK = "https://cloud.r-project.org") - extra <- getOption("renv.bootstrap.repos", default = default) - repos <- c(repos, extra) - - # remove duplicates that might've snuck in - dupes <- duplicated(repos) | duplicated(names(repos)) - repos[!dupes] - - } - - renv_bootstrap_repos_lockfile <- function() { - - lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock") - if (!file.exists(lockpath)) - return(NULL) - - lockfile <- tryCatch(renv_json_read(lockpath), error = identity) - if (inherits(lockfile, "error")) { - warning(lockfile) - return(NULL) - } - - repos <- lockfile$R$Repositories - if (length(repos) == 0) - return(NULL) - - keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1)) - vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1)) - names(vals) <- keys - - return(vals) - - } - - renv_bootstrap_download <- function(version) { - - # if the renv version number has 4 components, assume it must - # be retrieved via github - nv <- numeric_version(version) - components <- unclass(nv)[[1]] - - # if this appears to be a development version of 'renv', we'll - # try to restore from github - dev <- length(components) == 4L - - # begin collecting different methods for finding renv - methods <- c( - renv_bootstrap_download_tarball, - if (dev) - renv_bootstrap_download_github - else c( - renv_bootstrap_download_cran_latest, - renv_bootstrap_download_cran_archive - ) - ) - - for (method in methods) { - path <- tryCatch(method(version), error = identity) - if (is.character(path) && file.exists(path)) - return(path) - } - - stop("failed to download renv ", version) - - } - - renv_bootstrap_download_impl <- function(url, destfile) { - - mode <- "wb" - - # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715 - fixup <- - Sys.info()[["sysname"]] == "Windows" && - substring(url, 1L, 5L) == "file:" - - if (fixup) - mode <- "w+b" - - utils::download.file( - url = url, - destfile = destfile, - mode = mode, - quiet = TRUE - ) - - } - - renv_bootstrap_download_cran_latest <- function(version) { - - spec <- renv_bootstrap_download_cran_latest_find(version) - - message("* Downloading renv ", version, " ... ", appendLF = FALSE) - - type <- spec$type - repos <- spec$repos - - info <- tryCatch( - utils::download.packages( - pkgs = "renv", - destdir = tempdir(), - repos = repos, - type = type, - quiet = TRUE - ), - condition = identity - ) - - if (inherits(info, "condition")) { - message("FAILED") - return(FALSE) - } - - # report success and return - message("OK (downloaded ", type, ")") - info[1, 2] - - } - - renv_bootstrap_download_cran_latest_find <- function(version) { - - # check whether binaries are supported on this system - binary <- - getOption("renv.bootstrap.binary", default = TRUE) && - !identical(.Platform$pkgType, "source") && - !identical(getOption("pkgType"), "source") && - Sys.info()[["sysname"]] %in% c("Darwin", "Windows") - - types <- c(if (binary) "binary", "source") - - # iterate over types + repositories - for (type in types) { - for (repos in renv_bootstrap_repos()) { - - # retrieve package database - db <- tryCatch( - as.data.frame( - utils::available.packages(type = type, repos = repos), - stringsAsFactors = FALSE - ), - error = identity - ) - - if (inherits(db, "error")) - next - - # check for compatible entry - entry <- db[db$Package %in% "renv" & db$Version %in% version, ] - if (nrow(entry) == 0) - next - - # found it; return spec to caller - spec <- list(entry = entry, type = type, repos = repos) - return(spec) - - } - } - - # if we got here, we failed to find renv - fmt <- "renv %s is not available from your declared package repositories" - stop(sprintf(fmt, version)) - - } - - renv_bootstrap_download_cran_archive <- function(version) { - - name <- sprintf("renv_%s.tar.gz", version) - repos <- renv_bootstrap_repos() - urls <- file.path(repos, "src/contrib/Archive/renv", name) - destfile <- file.path(tempdir(), name) - - message("* Downloading renv ", version, " ... ", appendLF = FALSE) - - for (url in urls) { - - status <- tryCatch( - renv_bootstrap_download_impl(url, destfile), - condition = identity - ) - - if (identical(status, 0L)) { - message("OK") - return(destfile) - } - - } - - message("FAILED") - return(FALSE) - - } - - renv_bootstrap_download_tarball <- function(version) { - - # if the user has provided the path to a tarball via - # an environment variable, then use it - tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA) - if (is.na(tarball)) - return() - - # allow directories - info <- file.info(tarball, extra_cols = FALSE) - if (identical(info$isdir, TRUE)) { - name <- sprintf("renv_%s.tar.gz", version) - tarball <- file.path(tarball, name) - } - - # bail if it doesn't exist - if (!file.exists(tarball)) { - - # let the user know we weren't able to honour their request - fmt <- "* RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." - msg <- sprintf(fmt, tarball) - warning(msg) - - # bail - return() - - } - - fmt <- "* Bootstrapping with tarball at path '%s'." - msg <- sprintf(fmt, tarball) - message(msg) - - tarball - - } - - renv_bootstrap_download_github <- function(version) { - - enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") - if (!identical(enabled, "TRUE")) - return(FALSE) - - # prepare download options - pat <- Sys.getenv("GITHUB_PAT") - if (nzchar(Sys.which("curl")) && nzchar(pat)) { - fmt <- "--location --fail --header \"Authorization: token %s\"" - extra <- sprintf(fmt, pat) - saved <- options("download.file.method", "download.file.extra") - options(download.file.method = "curl", download.file.extra = extra) - on.exit(do.call(base::options, saved), add = TRUE) - } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { - fmt <- "--header=\"Authorization: token %s\"" - extra <- sprintf(fmt, pat) - saved <- options("download.file.method", "download.file.extra") - options(download.file.method = "wget", download.file.extra = extra) - on.exit(do.call(base::options, saved), add = TRUE) - } - - message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE) - - url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) - name <- sprintf("renv_%s.tar.gz", version) - destfile <- file.path(tempdir(), name) - - status <- tryCatch( - renv_bootstrap_download_impl(url, destfile), - condition = identity - ) - - if (!identical(status, 0L)) { - message("FAILED") - return(FALSE) - } - - message("OK") - return(destfile) - - } - - renv_bootstrap_install <- function(version, tarball, library) { - - # attempt to install it into project library - message("* Installing renv ", version, " ... ", appendLF = FALSE) - dir.create(library, showWarnings = FALSE, recursive = TRUE) - - # invoke using system2 so we can capture and report output - bin <- R.home("bin") - exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" - r <- file.path(bin, exe) - - args <- c( - "--vanilla", "CMD", "INSTALL", "--no-multiarch", - "-l", shQuote(path.expand(library)), - shQuote(path.expand(tarball)) - ) - - output <- system2(r, args, stdout = TRUE, stderr = TRUE) - message("Done!") - - # check for successful install - status <- attr(output, "status") - if (is.numeric(status) && !identical(status, 0L)) { - header <- "Error installing renv:" - lines <- paste(rep.int("=", nchar(header)), collapse = "") - text <- c(header, lines, output) - writeLines(text, con = stderr()) - } - - status - - } - - renv_bootstrap_platform_prefix <- function() { - - # construct version prefix - version <- paste(R.version$major, R.version$minor, sep = ".") - prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") - - # include SVN revision for development versions of R - # (to avoid sharing platform-specific artefacts with released versions of R) - devel <- - identical(R.version[["status"]], "Under development (unstable)") || - identical(R.version[["nickname"]], "Unsuffered Consequences") - - if (devel) - prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") - - # build list of path components - components <- c(prefix, R.version$platform) - - # include prefix if provided by user - prefix <- renv_bootstrap_platform_prefix_impl() - if (!is.na(prefix) && nzchar(prefix)) - components <- c(prefix, components) - - # build prefix - paste(components, collapse = "/") - - } - - renv_bootstrap_platform_prefix_impl <- function() { - - # if an explicit prefix has been supplied, use it - prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA) - if (!is.na(prefix)) - return(prefix) - - # if the user has requested an automatic prefix, generate it - auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) - if (auto %in% c("TRUE", "True", "true", "1")) - return(renv_bootstrap_platform_prefix_auto()) - - # empty string on failure - "" - - } - - renv_bootstrap_platform_prefix_auto <- function() { - - prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity) - if (inherits(prefix, "error") || prefix %in% "unknown") { - - msg <- paste( - "failed to infer current operating system", - "please file a bug report at https://github.com/rstudio/renv/issues", - sep = "; " - ) - - warning(msg) - - } - - prefix - - } - - renv_bootstrap_platform_os <- function() { - - sysinfo <- Sys.info() - sysname <- sysinfo[["sysname"]] - - # handle Windows + macOS up front - if (sysname == "Windows") - return("windows") - else if (sysname == "Darwin") - return("macos") - - # check for os-release files - for (file in c("/etc/os-release", "/usr/lib/os-release")) - if (file.exists(file)) - return(renv_bootstrap_platform_os_via_os_release(file, sysinfo)) - - # check for redhat-release files - if (file.exists("/etc/redhat-release")) - return(renv_bootstrap_platform_os_via_redhat_release()) - - "unknown" - - } - - renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) { - - # read /etc/os-release - release <- utils::read.table( - file = file, - sep = "=", - quote = c("\"", "'"), - col.names = c("Key", "Value"), - comment.char = "#", - stringsAsFactors = FALSE - ) - - vars <- as.list(release$Value) - names(vars) <- release$Key - - # get os name - os <- tolower(sysinfo[["sysname"]]) - - # read id - id <- "unknown" - for (field in c("ID", "ID_LIKE")) { - if (field %in% names(vars) && nzchar(vars[[field]])) { - id <- vars[[field]] - break - } - } - - # read version - version <- "unknown" - for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) { - if (field %in% names(vars) && nzchar(vars[[field]])) { - version <- vars[[field]] - break - } - } - - # join together - paste(c(os, id, version), collapse = "-") - - } - - renv_bootstrap_platform_os_via_redhat_release <- function() { - - # read /etc/redhat-release - contents <- readLines("/etc/redhat-release", warn = FALSE) - - # infer id - id <- if (grepl("centos", contents, ignore.case = TRUE)) - "centos" - else if (grepl("redhat", contents, ignore.case = TRUE)) - "redhat" - else - "unknown" - - # try to find a version component (very hacky) - version <- "unknown" - - parts <- strsplit(contents, "[[:space:]]")[[1L]] - for (part in parts) { - - nv <- tryCatch(numeric_version(part), error = identity) - if (inherits(nv, "error")) - next - - version <- nv[1, 1] - break - - } - - paste(c("linux", id, version), collapse = "-") - - } - - renv_bootstrap_library_root_name <- function(project) { - - # use project name as-is if requested - asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE") - if (asis) - return(basename(project)) - - # otherwise, disambiguate based on project's path - id <- substring(renv_bootstrap_hash_text(project), 1L, 8L) - paste(basename(project), id, sep = "-") - - } - - renv_bootstrap_library_root <- function(project) { - - prefix <- renv_bootstrap_profile_prefix() - - path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA) - if (!is.na(path)) - return(paste(c(path, prefix), collapse = "/")) - - path <- renv_bootstrap_library_root_impl(project) - if (!is.null(path)) { - name <- renv_bootstrap_library_root_name(project) - return(paste(c(path, prefix, name), collapse = "/")) - } - - renv_bootstrap_paths_renv("library", project = project) - - } - - renv_bootstrap_library_root_impl <- function(project) { - - root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA) - if (!is.na(root)) - return(root) - - type <- renv_bootstrap_project_type(project) - if (identical(type, "package")) { - userdir <- renv_bootstrap_user_dir() - return(file.path(userdir, "library")) - } - - } - - renv_bootstrap_validate_version <- function(version) { - - loadedversion <- utils::packageDescription("renv", fields = "Version") - if (version == loadedversion) - return(TRUE) - - # assume four-component versions are from GitHub; three-component - # versions are from CRAN - components <- strsplit(loadedversion, "[.-]")[[1]] - remote <- if (length(components) == 4L) - paste("rstudio/renv", loadedversion, sep = "@") - else - paste("renv", loadedversion, sep = "@") - - fmt <- paste( - "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", - "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", - "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", - sep = "\n" - ) - - msg <- sprintf(fmt, loadedversion, version, remote) - warning(msg, call. = FALSE) - - FALSE - - } - - renv_bootstrap_hash_text <- function(text) { - - hashfile <- tempfile("renv-hash-") - on.exit(unlink(hashfile), add = TRUE) - - writeLines(text, con = hashfile) - tools::md5sum(hashfile) - - } - - renv_bootstrap_load <- function(project, libpath, version) { - - # try to load renv from the project library - if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) - return(FALSE) - - # warn if the version of renv loaded does not match - renv_bootstrap_validate_version(version) - - # load the project - renv::load(project) - - TRUE - - } - - renv_bootstrap_profile_load <- function(project) { - - # if RENV_PROFILE is already set, just use that - profile <- Sys.getenv("RENV_PROFILE", unset = NA) - if (!is.na(profile) && nzchar(profile)) - return(profile) - - # check for a profile file (nothing to do if it doesn't exist) - path <- renv_bootstrap_paths_renv("profile", profile = FALSE) - if (!file.exists(path)) - return(NULL) - - # read the profile, and set it if it exists - contents <- readLines(path, warn = FALSE) - if (length(contents) == 0L) - return(NULL) - - # set RENV_PROFILE - profile <- contents[[1L]] - if (!profile %in% c("", "default")) - Sys.setenv(RENV_PROFILE = profile) - - profile - - } - - renv_bootstrap_profile_prefix <- function() { - profile <- renv_bootstrap_profile_get() - if (!is.null(profile)) - return(file.path("profiles", profile, "renv")) - } - - renv_bootstrap_profile_get <- function() { - profile <- Sys.getenv("RENV_PROFILE", unset = "") - renv_bootstrap_profile_normalize(profile) - } - - renv_bootstrap_profile_set <- function(profile) { - profile <- renv_bootstrap_profile_normalize(profile) - if (is.null(profile)) - Sys.unsetenv("RENV_PROFILE") - else - Sys.setenv(RENV_PROFILE = profile) - } - - renv_bootstrap_profile_normalize <- function(profile) { - - if (is.null(profile) || profile %in% c("", "default")) - return(NULL) - - profile - - } - - renv_bootstrap_path_absolute <- function(path) { - - substr(path, 1L, 1L) %in% c("~", "/", "\\") || ( - substr(path, 1L, 1L) %in% c(letters, LETTERS) && - substr(path, 2L, 3L) %in% c(":/", ":\\") - ) - - } - - renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) { - renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv") - root <- if (renv_bootstrap_path_absolute(renv)) NULL else project - prefix <- if (profile) renv_bootstrap_profile_prefix() - components <- c(root, renv, prefix, ...) - paste(components, collapse = "/") - } - - renv_bootstrap_project_type <- function(path) { - - descpath <- file.path(path, "DESCRIPTION") - if (!file.exists(descpath)) - return("unknown") - - desc <- tryCatch( - read.dcf(descpath, all = TRUE), - error = identity - ) - - if (inherits(desc, "error")) - return("unknown") - - type <- desc$Type - if (!is.null(type)) - return(tolower(type)) - - package <- desc$Package - if (!is.null(package)) - return("package") - - "unknown" - - } - - renv_bootstrap_user_dir <- function() { - dir <- renv_bootstrap_user_dir_impl() - path.expand(chartr("\\", "/", dir)) - } - - renv_bootstrap_user_dir_impl <- function() { - - # use local override if set - override <- getOption("renv.userdir.override") - if (!is.null(override)) - return(override) - - # use R_user_dir if available - tools <- asNamespace("tools") - if (is.function(tools$R_user_dir)) - return(tools$R_user_dir("renv", "cache")) - - # try using our own backfill for older versions of R - envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME") - for (envvar in envvars) { - root <- Sys.getenv(envvar, unset = NA) - if (!is.na(root)) - return(file.path(root, "R/renv")) - } - - # use platform-specific default fallbacks - if (Sys.info()[["sysname"]] == "Windows") - file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv") - else if (Sys.info()[["sysname"]] == "Darwin") - "~/Library/Caches/org.R-project.R/R/renv" - else - "~/.cache/R/renv" - - } - - - renv_json_read <- function(file = NULL, text = NULL) { - - text <- paste(text %||% read(file), collapse = "\n") - - # find strings in the JSON - pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - locs <- gregexpr(pattern, text, perl = TRUE)[[1]] - - # if any are found, replace them with placeholders - replaced <- text - strings <- character() - replacements <- character() - - if (!identical(c(locs), -1L)) { - - # get the string values - starts <- locs - ends <- locs + attr(locs, "match.length") - 1L - strings <- substring(text, starts, ends) - - # only keep those requiring escaping - strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE) - - # compute replacements - replacements <- sprintf('"\032%i\032"', seq_along(strings)) - - # replace the strings - mapply(function(string, replacement) { - replaced <<- sub(string, replacement, replaced, fixed = TRUE) - }, strings, replacements) - - } - - # transform the JSON into something the R parser understands - transformed <- replaced - transformed <- gsub("[[{]", "list(", transformed) - transformed <- gsub("[]}]", ")", transformed) - transformed <- gsub(":", "=", transformed, fixed = TRUE) - text <- paste(transformed, collapse = "\n") - - # parse it - json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]] - - # construct map between source strings, replaced strings - map <- as.character(parse(text = strings)) - names(map) <- as.character(parse(text = replacements)) - - # convert to list - map <- as.list(map) - - # remap strings in object - remapped <- renv_json_remap(json, map) - - # evaluate - eval(remapped, envir = baseenv()) - - } - - renv_json_remap <- function(json, map) { - - # fix names - if (!is.null(names(json))) { - lhs <- match(names(json), names(map), nomatch = 0L) - rhs <- match(names(map), names(json), nomatch = 0L) - names(json)[rhs] <- map[lhs] - } - - # fix values - if (is.character(json)) - return(map[[json]] %||% json) - - # handle true, false, null - if (is.name(json)) { - text <- as.character(json) - if (text == "true") - return(TRUE) - else if (text == "false") - return(FALSE) - else if (text == "null") - return(NULL) - } - - # recurse - if (is.recursive(json)) { - for (i in seq_along(json)) { - json[i] <- list(renv_json_remap(json[[i]], map)) - } - } - - json - - } - - # load the renv profile, if any - renv_bootstrap_profile_load(project) - - # construct path to library root - root <- renv_bootstrap_library_root(project) - - # construct library prefix for platform - prefix <- renv_bootstrap_platform_prefix() - - # construct full libpath - libpath <- file.path(root, prefix) - - # attempt to load - if (renv_bootstrap_load(project, libpath, version)) - return(TRUE) - - # load failed; inform user we're about to bootstrap - prefix <- paste("# Bootstrapping renv", version) - postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "") - header <- paste(prefix, postfix) - message(header) - - # perform bootstrap - bootstrap(version, libpath) - - # exit early if we're just testing bootstrap - if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) - return(TRUE) - - # try again to load - if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { - message("* Successfully installed and loaded renv ", version, ".") - return(renv::load()) - } - - # failed to download or load renv; warn the user - msg <- c( - "Failed to find an renv installation: the project will not be loaded.", - "Use `renv::activate()` to re-initialize the project." - ) - - warning(paste(msg, collapse = "\n"), call. = FALSE) - -}) diff --git a/Tools/flatpak/setup-rpkgs/setup-rpkgs.Rproj b/Tools/flatpak/setup-rpkgs/setup-rpkgs.Rproj deleted file mode 100644 index e83436a3e9..0000000000 --- a/Tools/flatpak/setup-rpkgs/setup-rpkgs.Rproj +++ /dev/null @@ -1,16 +0,0 @@ -Version: 1.0 - -RestoreWorkspace: Default -SaveWorkspace: Default -AlwaysSaveHistory: Default - -EnableCodeIndexing: Yes -UseSpacesForTab: Yes -NumSpacesForTab: 2 -Encoding: UTF-8 - -RnwWeave: Sweave -LaTeX: pdfLaTeX - -AutoAppendNewline: Yes -StripTrailingWhitespace: Yes diff --git a/Tools/macOS/Info.plist.in b/Tools/macOS/Info.plist.in index a5423ca3ea..04ce379b33 100644 --- a/Tools/macOS/Info.plist.in +++ b/Tools/macOS/Info.plist.in @@ -84,10 +84,17 @@ CFBundleTypeExtensions csv + txt tsv sav + zsav ods - txt + xls + xlsx + sas7bdat + sas7bcat + por + dta diff --git a/Tools/windows/BuildBotScript.cmd b/Tools/windows/BuildBotScript.cmd index 78d1d374e8..1cd574c76b 100644 --- a/Tools/windows/BuildBotScript.cmd +++ b/Tools/windows/BuildBotScript.cmd @@ -31,20 +31,18 @@ cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=D:/Qt cmake --build build --target all -cmake --build build --target windowsPreInstallHacks - cmake --build build --target install cmake --build build --target collect-junctions -robocopy .\build\Install .\build\InstallClean /e +robocopy .\build\Install .\build\InstallClean /e /nfl cmake --build build --target wix cmake --build build --target zip rmdir .\build\Install /s /q -robocopy .\build\InstallClean .\build\Install /e +robocopy .\build\InstallClean .\build\Install /e /nfl cmake --install build --component MSIX diff --git a/Tools/windows/CollectJunctions.cmd.in b/Tools/windows/CollectJunctions.cmd.in index 86ba3a0e9a..91fedda8cb 100644 --- a/Tools/windows/CollectJunctions.cmd.in +++ b/Tools/windows/CollectJunctions.cmd.in @@ -10,6 +10,8 @@ call "@VC_VARS_PATH_NATIVE@\vcvars64.bat" set PATH=@RINSIDE_PATH_NATIVE@\libs\x64;@RCPP_PATH_NATIVE@\libs\x64;@R_BIN_PATH_NATIVE@\x64;%QTVCDIR%;%PATH% set R_HOME=@R_HOME_PATH_NATIVE@ set JASPENGINE_LOCATION=@JASP_BINARY_DIR_NATIVE@\JASPEngine.exe +set R_LIBS=@JASP_BINARY_DIR_NATIVE@\Modules\Tools\junction_bootstrap_library;@R_HOME_PATH_NATIVE@\library + rem ---------------------- Collecting Junctions ------------------ diff --git a/Tools/windows/RecreateJunctions.cmd.in b/Tools/windows/RecreateJunctions.cmd.in index 8b70999c46..0c6505b71e 100644 --- a/Tools/windows/RecreateJunctions.cmd.in +++ b/Tools/windows/RecreateJunctions.cmd.in @@ -10,6 +10,7 @@ call "@VC_VARS_PATH_NATIVE@\vcvars64.bat" set PATH=@RINSIDE_PATH_NATIVE@\libs\x64;@RCPP_PATH_NATIVE@\libs\x64;@R_BIN_PATH_NATIVE@\x64;%QTVCDIR%;%PATH% set R_HOME=@R_HOME_PATH_NATIVE@ set JASPENGINE_LOCATION=@JASP_BINARY_DIR_NATIVE@\JASPEngine.exe +set R_LIBS=@JASP_BINARY_DIR_NATIVE@\Modules\Tools\junction_bootstrap_library;@R_HOME_PATH_NATIVE@\library rem ---------------------- Collecting Junctions ------------------ diff --git a/Tools/windows/RecursiveJunctionRemover.cmd.in b/Tools/windows/RecursiveJunctionRemover.cmd.in new file mode 100644 index 0000000000..5668d4ec2c --- /dev/null +++ b/Tools/windows/RecursiveJunctionRemover.cmd.in @@ -0,0 +1,2 @@ +rem Need to remove junctions from Modules/Tools +FOR /f "tokens=*" %%a in ('dir /AL /S /B @JASP_BINARY_DIR_NATIVE@\Install\Modules\Tools\') DO del /Q %%a \ No newline at end of file diff --git a/Tools/windows/exe/Assets/jasp_logo.bmp b/Tools/windows/exe/Assets/jasp_logo.bmp new file mode 100644 index 0000000000..f29e0ba502 Binary files /dev/null and b/Tools/windows/exe/Assets/jasp_logo.bmp differ diff --git a/Tools/windows/exe/Assets/jasp_logo_64x68.bmp b/Tools/windows/exe/Assets/jasp_logo_64x68.bmp new file mode 100644 index 0000000000..f3630e2371 Binary files /dev/null and b/Tools/windows/exe/Assets/jasp_logo_64x68.bmp differ diff --git a/Tools/windows/exe/Assets/jasp_pak.ico b/Tools/windows/exe/Assets/jasp_pak.ico new file mode 100644 index 0000000000..61df7ebaae Binary files /dev/null and b/Tools/windows/exe/Assets/jasp_pak.ico differ diff --git a/Tools/windows/exe/Assets/jasp_wave_banner.bmp b/Tools/windows/exe/Assets/jasp_wave_banner.bmp new file mode 100644 index 0000000000..c245a31e44 Binary files /dev/null and b/Tools/windows/exe/Assets/jasp_wave_banner.bmp differ diff --git a/Tools/windows/exe/ExePackerScript.iss.in b/Tools/windows/exe/ExePackerScript.iss.in new file mode 100644 index 0000000000..0579906143 --- /dev/null +++ b/Tools/windows/exe/ExePackerScript.iss.in @@ -0,0 +1,205 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define MyAppName "JASP" +#define MyAppVersion "@JASP_VERSION_MAJOR@.@JASP_VERSION_MINOR@.@JASP_VERSION_PATCH@@JASP_VERSION_MSIX_PATCH_POSTFIX@.@JASP_VERSION_TWEAK@" +#define MyAppPublisher "The JASP Team." +#define MyAppURL "https://jasp-stats.org/" +#define MyAppExeName "JASP.exe" +#define MyAppAssocName MyAppName + " File" +#define MyAppAssocExt ".jasp" +#define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt + +#define CsvAssocName "CSV File" +#define CsvAssocExt ".csv" +#define CsvAssocKey StringChange(CsvAssocName, " ", "") + CsvAssocExt + +#define OdsAssocName "Open Document Spreadsheet File" +#define OdsAssocExt ".ods" +#define OdsAssocKey StringChange(OdsAssocName, " ", "") + OdsAssocExt + +#define XlsAssocName "Excel(97-2003) File" +#define XlsAssocExt ".xls" +#define XlsAssocKey StringChange(XlsAssocName, " ", "") + XlsAssocExt + +#define XlsxAssocName "Excel File" +#define XlsxAssocExt ".xlsx" +#define XlsxAssocKey StringChange(XlsxAssocName, " ", "") + XlsxAssocExt + +#define SavAssocName "SPSS Dataset File" +#define SavAssocExt ".sav" +#define SavAssocKey StringChange(SavAssocName, " ", "") + SavAssocExt + +#define ZsavAssocName "SPSS Dataset File" +#define ZsavAssocExt ".zsav" +#define ZsavAssocKey StringChange(ZsavAssocName, " ", "") + ZsavAssocExt + +#define XptAssocName "SPSS Dataset File" +#define XptAssocExt ".xpt" +#define XptAssocKey StringChange(XptAssocName, " ", "") + XptAssocExt + +#define PorAssocName "SPSS Dataset File" +#define PorAssocExt ".por" +#define PorAssocKey StringChange(PorAssocName, " ", "") + PorAssocExt + +#define DtaAssocName "STATA Dataset File" +#define DtaAssocExt ".dta" +#define DtaAssocKey StringChange(DtaAssocName, " ", "") + DtaAssocExt + +#define SasAssocName "SAS Dataset File" +#define SasAssocExt ".sas7bdat" +#define SasAssocKey StringChange(SasAssocName, " ", "") + SasAssocExt + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{D650DE0B-5D76-43E0-B9CF-91F8B9A429DF} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={autopf}\{#MyAppName} +ChangesAssociations=yes +DisableProgramGroupPage=yes +LicenseFile=@CMAKE_SOURCE_DIR@\Tools\windows\jaspLicense.rtf +;InfoAfterFile=JASP_INSTALL_DIR_NATIVE@\release_note.txt +; Uncomment the following line to run in non administrative install mode (install for current user only.) +;PrivilegesRequired=lowest +PrivilegesRequiredOverridesAllowed=dialog +OutputDir=@JASP_BINARY_DIR_NATIVE@\JASP\JASPEXE +OutputBaseFilename=JASP_{#MyAppVersion}_Setup +SetupIconFile=@CMAKE_SOURCE_DIR@\Tools\windows\exe\Assets\jasp_pak.ico +Compression=lzma +SolidCompression=yes +WizardStyle=modern +WizardImageStretch=yes +WizardSmallImageFile=@CMAKE_SOURCE_DIR@\Tools\windows\exe\Assets\jasp_logo.bmp,@CMAKE_SOURCE_DIR@\Tools\windows\exe\Assets\jasp_logo_64x68.bmp +WizardImageFile=@CMAKE_SOURCE_DIR@\Tools\windows\exe\Assets\jasp_wave_banner.bmp + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" +Name: "armenian"; MessagesFile: "compiler:Languages\Armenian.isl" +Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl" +Name: "bulgarian"; MessagesFile: "compiler:Languages\Bulgarian.isl" +Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl" +Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl" +Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl" +Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl" +Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" +Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl" +Name: "french"; MessagesFile: "compiler:Languages\French.isl" +Name: "german"; MessagesFile: "compiler:Languages\German.isl" +Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl" +Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl" +Name: "icelandic"; MessagesFile: "compiler:Languages\Icelandic.isl" +Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" +Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" +Name: "korean"; MessagesFile: "compiler:Languages\Korean.isl" +Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl" +Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl" +Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl" +Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" +Name: "slovak"; MessagesFile: "compiler:Languages\Slovak.isl" +Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl" +Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl" +Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl" +Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl" +;Extra language files +Name: "zh"; MessagesFile: "compiler:Languages\ChineseSimplified.isl" +Name: "zhTW"; MessagesFile: "compiler:Languages\ChineseTraditional.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "@JASP_INSTALL_DIR_NATIVE@\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion +Source: "@JASP_INSTALL_DIR_NATIVE@\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Registry] +; associate .jasp +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".jasp"; ValueData: "" +; associate .csv +Root: HKA; Subkey: "Software\Classes\{#CsvAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#CsvAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#CsvAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#CsvAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#CsvAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#CsvAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".csv"; ValueData: "" +; associate .ods +Root: HKA; Subkey: "Software\Classes\{#OdsAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#OdsAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#OdsAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#OdsAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#OdsAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#OdsAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".ods"; ValueData: "" +; associate .xls +Root: HKA; Subkey: "Software\Classes\{#XlsAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#XlsAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#XlsAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#XlsAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#XlsAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#XlsAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".xls"; ValueData: "" +; associate .xlsx +Root: HKA; Subkey: "Software\Classes\{#XlsxAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#XlsxAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#XlsxAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#XlsxAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#XlsxAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#XlsxAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".xlsx"; ValueData: "" +; associate .sav +Root: HKA; Subkey: "Software\Classes\{#SavAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#SavAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#SavAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#SavAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#SavAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#SavAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".sav"; ValueData: "" +; associate .zsav +Root: HKA; Subkey: "Software\Classes\{#ZsavAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#ZsavAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#ZsavAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#ZsavAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#ZsavAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#ZsavAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".zsav"; ValueData: "" +; associate .xpt +Root: HKA; Subkey: "Software\Classes\{#XptAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#XptAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#XptAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#XptAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#XptAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#XptAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".xpt"; ValueData: "" +; associate .por +Root: HKA; Subkey: "Software\Classes\{#PorAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#PorAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#PorAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#PorAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#PorAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#PorAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".por"; ValueData: "" +; associate .dta +Root: HKA; Subkey: "Software\Classes\{#DtaAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#DtaAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#DtaAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#DtaAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#DtaAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#DtaAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".dta"; ValueData: "" +; associate .sas7bdat +Root: HKA; Subkey: "Software\Classes\{#SasAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#SasAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#SasAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#SasAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#SasAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\icon.ico" +Root: HKA; Subkey: "Software\Classes\{#SasAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".sas7bdat"; ValueData: "" + +;Start of Registry for Windows GameDVR +Root: HKA; Subkey: "Software\Microsoft\Windows\CurrentVersion\GameDVR"; Flags: uninsdeletekeyifempty; Check: not IsAdminInstallMode +Root: HKA; Subkey: "Software\Microsoft\Windows\CurrentVersion\GameDVR"; ValueType: dword; ValueName: "AppCaptureEnabled"; ValueData: $00000000; Flags: uninsdeletevalue; Check: not IsAdminInstallMode +Root: HKA; Subkey: "System\GameConfigStore"; Flags: uninsdeletekeyifempty; Check: not IsAdminInstallMode +Root: HKA; Subkey: "System\GameConfigStore"; ValueType: dword; ValueName: "GameDVR_Enabled"; ValueData: $00000000; Flags: uninsdeletevalue; Check: not IsAdminInstallMode +Root: HKA; Subkey: "Software\Policies\Microsoft\Windows\GameDVR"; Flags: uninsdeletekeyifempty; Check: IsAdminInstallMode +Root: HKA; Subkey: "Software\Policies\Microsoft\Windows\GameDVR"; ValueType: dword; ValueName: "AllowGameDVR"; ValueData: $00000000; Flags: uninsdeletevalue; Check: IsAdminInstallMode +;End of Registry for Windows GameDVR + +[Icons] +Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\icon.ico" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +;When should we running the: Parameters: "--junctions"; +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent diff --git a/Tools/windows/msix/AppxManifest-nightly.xml.in b/Tools/windows/msix/AppxManifest-nightly.xml.in index c43481c078..c06d60d3bd 100644 --- a/Tools/windows/msix/AppxManifest-nightly.xml.in +++ b/Tools/windows/msix/AppxManifest-nightly.xml.in @@ -55,6 +55,8 @@ .csv .sav .ods + .xls + .xlsx .zsav .xpt .por diff --git a/Tools/windows/msix/AppxManifest-sideload.xml.in b/Tools/windows/msix/AppxManifest-sideload.xml.in index 56dbe8ca11..ba08066439 100644 --- a/Tools/windows/msix/AppxManifest-sideload.xml.in +++ b/Tools/windows/msix/AppxManifest-sideload.xml.in @@ -55,6 +55,8 @@ .csv .sav .ods + .xls + .xlsx .zsav .xpt .por diff --git a/Tools/windows/msix/AppxManifest-store-beta.xml.in b/Tools/windows/msix/AppxManifest-store-beta.xml.in index ab33bc8fd0..fae2b0ade1 100644 --- a/Tools/windows/msix/AppxManifest-store-beta.xml.in +++ b/Tools/windows/msix/AppxManifest-store-beta.xml.in @@ -55,6 +55,8 @@ .csv .sav .ods + .xls + .xlsx .zsav .xpt .por diff --git a/Tools/windows/msix/AppxManifest-store.xml.in b/Tools/windows/msix/AppxManifest-store.xml.in index 84eebdd1c5..82b7a389f6 100644 --- a/Tools/windows/msix/AppxManifest-store.xml.in +++ b/Tools/windows/msix/AppxManifest-store.xml.in @@ -55,6 +55,8 @@ .csv .sav .ods + .xls + .xlsx .zsav .xpt .por diff --git a/Tools/windows/windowsPreInstallHacks.cmd.in b/Tools/windows/windowsPreInstallHacks.cmd.in deleted file mode 100644 index 88eb69514f..0000000000 --- a/Tools/windows/windowsPreInstallHacks.cmd.in +++ /dev/null @@ -1,17 +0,0 @@ -rem This file is generated from Tools/windows/windowsPostInstallHacks.cmd.in, if you want to change it, -rem be aware that it will be overwritten. You can edit the template file, and rerun the CMake -rem to see your changes here. -rem -rem You don't need to run this file manually, you can ask CMake to run it for you using -rem `cmake --build . --target windowsPostInstallHacks` - - -rem -------- Temporary fix to transfer modules to cache -------- - -echo Transfering module folders to renv-cache (we should get rid of this in the future) - -pushd . -cd @JASP_BINARY_DIR_NATIVE@\Modules\ -mkdir renv-cache\tmpSolution -For /D %%G IN (jasp*) do ( move /Y %%G\%%G renv-cache\tmpSolution\%%G && mklink /J %%G\%%G renv-cache\tmpSolution\%%G ) -popd diff --git a/Tools/windows/zip/ZIP.cmd.in b/Tools/windows/zip/ZIP.cmd.in index e63f3eaae9..bb856fc180 100644 --- a/Tools/windows/zip/ZIP.cmd.in +++ b/Tools/windows/zip/ZIP.cmd.in @@ -12,6 +12,14 @@ setlocal EnableDelayedExpansion rem ---------------------- Packing ------------------------------- echo Making zip-version of installer +where /q zip +IF ERRORLEVEL 1 ( powershell Compress-Archive -Update "@JASP_INSTALL_DIR_NATIVE@\*" "@JASP_BINARY_DIR_NATIVE@\JASP\JASP.zip" - -endlocal \ No newline at end of file +) ELSE ( +rem Using gnu zip +pushd . +cd /d "@JASP_INSTALL_DIR_NATIVE@\*" +zip -9 -q -r "@JASP_BINARY_DIR_NATIVE@\JASP\JASP.zip" . +popd +) +endlocal diff --git a/conanfile.txt b/conanfile.txt index f0e1d80fcf..d99bc15de4 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -15,13 +15,15 @@ jsoncpp/1.9.5 openssl/3.0.10 bison/3.7.6 brotli/1.0.9 -sqlite3/3.38.5 +sqlite3/3.46.0 gmp/6.3.0 mpfr/4.2.1 +freexl/2.0.0 [generators] CMakeDeps CMakeToolchain [options] -brotli/:shared=True \ No newline at end of file +brotli/:shared=True +sqlite3*:max_column=32767