diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index e785aafdac..50650a7571 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -29,6 +29,7 @@ jobs:
libjson-perl \
libjson-xs-perl \
liblocale-maketext-lexicon-perl \
+ libmojolicious-perl \
libtest2-suite-perl \
libtie-ixhash-perl \
libuuid-tiny-perl \
diff --git a/cpanfile b/cpanfile
index 46f288e3fd..ca6cbe1f03 100644
--- a/cpanfile
+++ b/cpanfile
@@ -18,6 +18,7 @@ on runtime => sub {
requires 'JSON::XS';
requires 'Locale::Maketext';
requires 'Locale::Maketext::Lexicon';
+ requires 'Mojolicious';
requires 'Tie::IxHash';
requires 'Types::Serialiser';
requires 'UUID::Tiny';
diff --git a/docker/pg.Dockerfile b/docker/pg.Dockerfile
index ffcf22c772..36741fc5ff 100644
--- a/docker/pg.Dockerfile
+++ b/docker/pg.Dockerfile
@@ -21,6 +21,7 @@ RUN apt-get update \
libjson-perl \
libjson-xs-perl \
liblocale-maketext-lexicon-perl \
+ libmojolicious-perl \
libtest2-suite-perl \
libtie-ixhash-perl \
libuuid-tiny-perl \
diff --git a/htdocs/js/Essay/essay.js b/htdocs/js/Essay/essay.js
index 2d0fab6b38..c3a6a59def 100644
--- a/htdocs/js/Essay/essay.js
+++ b/htdocs/js/Essay/essay.js
@@ -1,17 +1,28 @@
'use strict';
(() => {
- const addPreviewButton = (latexEntry) => {
- if (latexEntry.dataset.previewBtnAdded) return;
- latexEntry.dataset.previewBtnAdded = 'true';
+ const initializePreviewButton = (latexEntry) => {
+ if (latexEntry.dataset.previewBtnInitialized) return;
+ latexEntry.dataset.previewBtnInitialized = 'true';
- const buttonContainer = document.createElement('div');
- buttonContainer.classList.add('latexentry-button-container', 'mt-1');
+ const buttonContainer =
+ document.getElementById(`${latexEntry.id}-latexentry-button-container`) || document.createElement('div');
- const button = document.createElement('button');
- button.type = 'button';
- button.classList.add('latexentry-preview', 'btn', 'btn-secondary', 'btn-sm');
- button.textContent = 'Preview';
+ if (!buttonContainer.classList.contains('latexentry-button-container')) {
+ buttonContainer.classList.add('latexentry-button-container', 'mt-1');
+ buttonContainer.id = `${latexEntry.id}-latexentry-button-container`;
+ latexEntry.after(buttonContainer);
+ }
+
+ const button = buttonContainer.querySelector('.latexentry-preview') || document.createElement('button');
+
+ if (!button.classList.contains('latexentry-preview')) {
+ button.type = 'button';
+ button.classList.add('latexentry-preview', 'btn', 'btn-secondary', 'btn-sm');
+ button.textContent = 'Preview';
+
+ buttonContainer.append(button);
+ }
button.addEventListener('click', () => {
button.dataset.bsContent = latexEntry.value
@@ -49,19 +60,16 @@
popover.show();
}
});
-
- buttonContainer.append(button);
- latexEntry.after(buttonContainer);
};
- document.querySelectorAll('.latexentryfield').forEach(addPreviewButton);
+ document.querySelectorAll('.latexentryfield').forEach(initializePreviewButton);
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
for (const node of mutation.addedNodes) {
if (node instanceof Element) {
- if (node.classList.contains('latexentryfield')) addPreviewButton(node);
- else node.querySelectorAll('.latexentryfield').forEach(addPreviewButton);
+ if (node.classList.contains('latexentryfield')) initializePreviewButton(node);
+ else node.querySelectorAll('.latexentryfield').forEach(initializePreviewButton);
}
}
}
diff --git a/htdocs/js/Feedback/feedback.js b/htdocs/js/Feedback/feedback.js
new file mode 100644
index 0000000000..b7271cee39
--- /dev/null
+++ b/htdocs/js/Feedback/feedback.js
@@ -0,0 +1,49 @@
+(() => {
+ const initializeFeedback = (feedbackBtn) => {
+ if (feedbackBtn.dataset.popoverInitialized) return;
+ feedbackBtn.dataset.popoverInitialized = 'true';
+
+ new bootstrap.Popover(feedbackBtn, { sanitize: false, container: feedbackBtn.parentElement });
+
+ // Render MathJax previews.
+ if (window.MathJax) {
+ feedbackBtn.addEventListener('show.bs.popover', () => {
+ MathJax.startup.promise = MathJax.startup.promise.then(() => MathJax.typesetPromise(['.popover-body']));
+ });
+ }
+
+ feedbackBtn.addEventListener('shown.bs.popover', () => {
+ const bsPopover = bootstrap.Popover.getInstance(feedbackBtn);
+
+ // Execute javascript in the answer preview.
+ bsPopover.tip?.querySelectorAll('script').forEach((origScript) => {
+ const newScript = document.createElement('script');
+ Array.from(origScript.attributes).forEach((attr) => newScript.setAttribute(attr.name, attr.value));
+ newScript.appendChild(document.createTextNode(origScript.innerHTML));
+ origScript.parentNode.replaceChild(newScript, origScript);
+ });
+
+ // Make a click on the popover header close the popover.
+ bsPopover.tip?.querySelector('.popover-header')?.addEventListener('click', () => bsPopover?.hide());
+ });
+ };
+
+ // Setup feedback popovers already on the page.
+ document.querySelectorAll('.ww-feedback-btn').forEach(initializeFeedback);
+
+ // Deal with feedback popovers that are added to the page later.
+ const observer = new MutationObserver((mutationsList) => {
+ mutationsList.forEach((mutation) => {
+ mutation.addedNodes.forEach((node) => {
+ if (node instanceof Element) {
+ if (node.classList.contains('ww-feedback-btn')) initializeFeedback(node.firstElementChild);
+ else node.querySelectorAll('.ww-feedback-btn').forEach(initializeFeedback);
+ }
+ });
+ });
+ });
+ observer.observe(document.body, { childList: true, subtree: true });
+
+ // Stop the mutation observer when the window is closed.
+ window.addEventListener('unload', () => observer.disconnect());
+})();
diff --git a/htdocs/js/InputColor/color.js b/htdocs/js/InputColor/color.js
deleted file mode 100644
index 025301ac18..0000000000
--- a/htdocs/js/InputColor/color.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// For coloring the input elements with the proper color based on whether they are correct or incorrect.
-
-(() => {
- const setupAnswerLink = (answerLink) => {
- const answerId = answerLink.dataset.answerId;
- const answerInput = document.getElementById(answerId);
-
- const type = answerLink.parentNode.classList.contains('ResultsWithoutError') ? 'correct' : 'incorrect';
- const radioGroups = {};
-
- // Color all of the inputs and selects associated with this answer. On the first pass radio inputs are
- // collected into groups by name, and on the second pass the checked radio is highlighted, or if none are
- // checked all are highlighted.
- document.querySelectorAll(`input[name*=${answerId}],select[name*=${answerId}`)
- .forEach((input) => {
- if (input.type.toLowerCase() === 'radio') {
- if (!radioGroups[input.name]) radioGroups[input.name] = [];
- radioGroups[input.name].push(input);
- } else {
- if (input.type.toLowerCase() === 'text') {
- if (type === 'correct' || input.value !== '') input.classList.add(type);
- } else
- input.classList.add(type);
- }
- });
-
- Object.values(radioGroups).forEach((group) => {
- if (group.every((radio) => {
- if (radio.checked) {
- radio.classList.add(type);
- return false;
- }
- return true;
- })) {
- group.forEach((radio) => radio.classList.add(type));
- }
- });
-
- if (answerInput) {
- answerLink.addEventListener('click', (e) => {
- e.preventDefault();
- answerInput.focus();
- });
- } else {
- answerLink.href = '';
- }
- };
-
- // Color inputs already on the page.
- document.querySelectorAll('td a[data-answer-id]').forEach(setupAnswerLink);
-
- // Deal with inputs that are added to the page later.
- const observer = new MutationObserver((mutationsList) => {
- mutationsList.forEach((mutation) => {
- mutation.addedNodes.forEach((node) => {
- if (node instanceof Element) {
- if (node.type && node.type.toLowerCase() === 'td' && node.firstElementChild
- && node.firstElementChild.type.toLowerCase() == 'a' && node.firstElementChild.dataset.answerId)
- setupAnswerLink(node.firstElementChild);
- else node.querySelectorAll('td a[data-answer-id]').forEach(setupAnswerLink);
- }
- });
- });
- });
- observer.observe(document.body, { childList: true, subtree: true });
-
- // Stop the mutation observer when the window is closed.
- window.addEventListener('unload', () => observer.disconnect());
-})();
diff --git a/htdocs/js/LiveGraphics/liveGraphics.js b/htdocs/js/LiveGraphics/liveGraphics.js
index 6e6ce88e88..fc16a4a71b 100644
--- a/htdocs/js/LiveGraphics/liveGraphics.js
+++ b/htdocs/js/LiveGraphics/liveGraphics.js
@@ -1,913 +1,882 @@
// liveGraphics.js
// This is a javascript based replacement for the LiveGraphics3D java library
-//
+//
// This program is free software; you can redistribute it and/or modify it under
// the terms of either: (a) the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option) any later
// version, or (b) the "Artistic License" which comes with this package.
-//
+//
// 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 either the GNU General Public License or the
// Artistic License for more details.
var LiveGraphics3D = function (container, options) {
- var my = this;
-
- // define x3d container and scene
- var x3d = $("").appendTo(container)
- .css('width',options.width+'px')
- .css('height',options.height+'px')
- .css('border','none')
- .css('overflow','hidden')
- .attr('swfpath','/webwork2_files/js/vendor/x3dom/x3dom.swf');
-
- $("
").addClass('sr-only')
- .text('A manipulable 3d graph.')
- .prependTo(container);
-
- // disable mousewheel on container because its used for zoom
- $(x3d).bind('DOMMouseScroll mousewheel',function(event) {
- event.preventDefault();
- });
-
- var scene = $("").appendTo(x3d);
-
- // extend options by default values
- var defaults = {
- width : 200,
- height : 200,
- // Controls if axis are shown or not
- showAxes : false,
- // If the axis are shown determines if a full cube is drawn or just
- // the three axis lines
- showAxesCube : true,
- numTicks : 4,
- tickSize : .1,
- tickFontSize : .15,
- axisKey : ['X','Y','Z'],
- // Determines if the polygons forming the surface have their edges
- // drawn
- drawMesh : true,
- };
-
- var options = $.extend({}, defaults, options);
-
- //global variables
- //arrays of colors and thicknesses drawn from input
- var colors = {};
- var lineThickness = {};
-
- //scale elements capturing scale of plotted data
- var windowScale;
- var coordMins;
- var coordMaxs;
-
- //block indexes are used to associate objects to colors and thicknesses
- var blockIndex = 0;
- var surfaceBlockIndex = 0;
-
- //data from input
- var surfaceCoords = [];
- var surfaceIndex = [];
- var lineCoords = [];
- var lonePoints = [];
- var loneLabels = [];
-
- // This is the color map for shading surfaces based on elevation
- var colormap = [
- [0.00000, 0.00000, 0.50000],
- [0.00000, 0.00000, 0.56349],
- [0.00000, 0.00000, 0.62698],
- [0.00000, 0.00000, 0.69048],
- [0.00000, 0.00000, 0.75397],
- [0.00000, 0.00000, 0.81746],
- [0.00000, 0.00000, 0.88095],
- [0.00000, 0.00000, 0.94444],
- [0.00000, 0.00794, 1.00000],
- [0.00000, 0.07143, 1.00000],
- [0.00000, 0.13492, 1.00000],
- [0.00000, 0.19841, 1.00000],
- [0.00000, 0.26190, 1.00000],
- [0.00000, 0.32540, 1.00000],
- [0.00000, 0.38889, 1.00000],
- [0.00000, 0.45238, 1.00000],
- [0.00000, 0.51587, 1.00000],
- [0.00000, 0.57937, 1.00000],
- [0.00000, 0.64286, 1.00000],
- [0.00000, 0.70635, 1.00000],
- [0.00000, 0.76984, 1.00000],
- [0.00000, 0.83333, 1.00000],
- [0.00000, 0.89683, 1.00000],
- [0.00000, 0.96032, 1.00000],
- [0.02381, 1.00000, 0.97619],
- [0.08730, 1.00000, 0.91270],
- [0.15079, 1.00000, 0.84921],
- [0.21429, 1.00000, 0.78571],
- [0.27778, 1.00000, 0.72222],
- [0.34127, 1.00000, 0.65873],
- [0.40476, 1.00000, 0.59524],
- [0.46825, 1.00000, 0.53175],
- [0.53175, 1.00000, 0.46825],
- [0.59524, 1.00000, 0.40476],
- [0.65873, 1.00000, 0.34127],
- [0.72222, 1.00000, 0.27778],
- [0.78571, 1.00000, 0.21429],
- [0.84921, 1.00000, 0.15079],
- [0.91270, 1.00000, 0.08730],
- [0.97619, 1.00000, 0.02381],
- [1.00000, 0.96032, 0.00000],
- [1.00000, 0.89683, 0.00000],
- [1.00000, 0.83333, 0.00000],
- [1.00000, 0.76984, 0.00000],
- [1.00000, 0.70635, 0.00000],
- [1.00000, 0.64286, 0.00000],
- [1.00000, 0.57937, 0.00000],
- [1.00000, 0.51587, 0.00000],
- [1.00000, 0.45238, 0.00000],
- [1.00000, 0.38889, 0.00000],
- [1.00000, 0.32540, 0.00000],
- [1.00000, 0.26190, 0.00000],
- [1.00000, 0.19841, 0.00000],
- [1.00000, 0.13492, 0.00000],
- [1.00000, 0.07143, 0.00000],
- [1.00000, 0.00794, 0.00000],
- [0.94444, 0.00000, 0.00000],
- [0.88095, 0.00000, 0.00000],
- [0.81746, 0.00000, 0.00000],
- [0.75397, 0.00000, 0.00000],
- [0.69048, 0.00000, 0.00000],
- [0.62698, 0.00000, 0.00000],
- [0.56349, 0.00000, 0.00000],
- [0.50000, 0.00000, 0.00000]];
-
- // intialization function. This takes the mathmatica data string
- // and actually sets up the dom structure for the graph.
- // the actual graphing is done automatically by x3dom
- var initialize = function (datastring) {
-
- // parse matlab string
- parseLive3DData(datastring);
-
- // find extremum for axis and window scale
- setExtremum();
-
- // set up scene veiwpoint to be along the x axis looking to the
- // origin
- scene.append($("").
- attr('rotation',[1,0,0,Math.PI/2])
- .append($("")
- .attr( "fieldofview", .9)
- .attr( "position", [2*windowScale,0,0] )
- .attr( "orientation", [0,1,0,Math.PI/2])));
-
- scene.append($('').attr('skycolor','1 1 1'));
-
- // draw components of scene
- if (options.showAxes) {
- drawAxes();
- }
-
- drawSurface();
- drawLines();
- drawLonePoints();
- drawLoneLabels();
-
- };
-
- var parseLive3DData = function(text) {
- // Set up variables
- $.each(options.vars, function (name, data) {
- eval(name+'='+data);
+ // define x3d container and scene
+ var x3d = $('')
+ .appendTo(container)
+ .css('width', options.width + 'px')
+ .css('height', options.height + 'px')
+ .css('border', 'none')
+ .css('overflow', 'hidden');
+
+ $('').addClass('sr-only').text('A manipulable 3d graph.').prependTo(container);
+
+ // disable mousewheel on container because its used for zoom
+ $(x3d).bind('DOMMouseScroll mousewheel', function (event) {
+ event.preventDefault();
});
- // this parses axes commands.
- if (text.match(/Axes\s*->\s*True/)) {
- options.showAxes = true;
- }
+ var scene = $('').appendTo(x3d);
+
+ // extend options by default values
+ var defaults = {
+ width: 200,
+ height: 200,
+ // Controls if axis are shown or not
+ showAxes: false,
+ // If the axis are shown determines if a full cube is drawn or just
+ // the three axis lines
+ showAxesCube: true,
+ numTicks: 4,
+ tickSize: 0.1,
+ tickFontSize: 0.15,
+ axisKey: ['X', 'Y', 'Z'],
+ // Determines if the polygons forming the surface have their edges
+ // drawn
+ drawMesh: true
+ };
+
+ var options = $.extend({}, defaults, options);
+
+ //global variables
+ //arrays of colors and thicknesses drawn from input
+ var colors = {};
+ var lineThickness = {};
+
+ //scale elements capturing scale of plotted data
+ var windowScale;
+ var coordMins;
+ var coordMaxs;
+
+ //block indexes are used to associate objects to colors and thicknesses
+ var blockIndex = 0;
+ var surfaceBlockIndex = 0;
+
+ //data from input
+ var surfaceCoords = [];
+ var surfaceIndex = [];
+ var lineCoords = [];
+ var lonePoints = [];
+ var loneLabels = [];
+
+ // This is the color map for shading surfaces based on elevation
+ var colormap = [
+ [0.0, 0.0, 0.5],
+ [0.0, 0.0, 0.56349],
+ [0.0, 0.0, 0.62698],
+ [0.0, 0.0, 0.69048],
+ [0.0, 0.0, 0.75397],
+ [0.0, 0.0, 0.81746],
+ [0.0, 0.0, 0.88095],
+ [0.0, 0.0, 0.94444],
+ [0.0, 0.00794, 1.0],
+ [0.0, 0.07143, 1.0],
+ [0.0, 0.13492, 1.0],
+ [0.0, 0.19841, 1.0],
+ [0.0, 0.2619, 1.0],
+ [0.0, 0.3254, 1.0],
+ [0.0, 0.38889, 1.0],
+ [0.0, 0.45238, 1.0],
+ [0.0, 0.51587, 1.0],
+ [0.0, 0.57937, 1.0],
+ [0.0, 0.64286, 1.0],
+ [0.0, 0.70635, 1.0],
+ [0.0, 0.76984, 1.0],
+ [0.0, 0.83333, 1.0],
+ [0.0, 0.89683, 1.0],
+ [0.0, 0.96032, 1.0],
+ [0.02381, 1.0, 0.97619],
+ [0.0873, 1.0, 0.9127],
+ [0.15079, 1.0, 0.84921],
+ [0.21429, 1.0, 0.78571],
+ [0.27778, 1.0, 0.72222],
+ [0.34127, 1.0, 0.65873],
+ [0.40476, 1.0, 0.59524],
+ [0.46825, 1.0, 0.53175],
+ [0.53175, 1.0, 0.46825],
+ [0.59524, 1.0, 0.40476],
+ [0.65873, 1.0, 0.34127],
+ [0.72222, 1.0, 0.27778],
+ [0.78571, 1.0, 0.21429],
+ [0.84921, 1.0, 0.15079],
+ [0.9127, 1.0, 0.0873],
+ [0.97619, 1.0, 0.02381],
+ [1.0, 0.96032, 0.0],
+ [1.0, 0.89683, 0.0],
+ [1.0, 0.83333, 0.0],
+ [1.0, 0.76984, 0.0],
+ [1.0, 0.70635, 0.0],
+ [1.0, 0.64286, 0.0],
+ [1.0, 0.57937, 0.0],
+ [1.0, 0.51587, 0.0],
+ [1.0, 0.45238, 0.0],
+ [1.0, 0.38889, 0.0],
+ [1.0, 0.3254, 0.0],
+ [1.0, 0.2619, 0.0],
+ [1.0, 0.19841, 0.0],
+ [1.0, 0.13492, 0.0],
+ [1.0, 0.07143, 0.0],
+ [1.0, 0.00794, 0.0],
+ [0.94444, 0.0, 0.0],
+ [0.88095, 0.0, 0.0],
+ [0.81746, 0.0, 0.0],
+ [0.75397, 0.0, 0.0],
+ [0.69048, 0.0, 0.0],
+ [0.62698, 0.0, 0.0],
+ [0.56349, 0.0, 0.0],
+ [0.5, 0.0, 0.0]
+ ];
+
+ // intialization function. This takes the mathmatica data string
+ // and actually sets up the dom structure for the graph.
+ // the actual graphing is done automatically by x3dom
+ var initialize = function (datastring) {
+ // parse matlab string
+ parseLive3DData(datastring);
+
+ // find extremum for axis and window scale
+ setExtremum();
+
+ // set up scene veiwpoint to be along the x axis looking to the
+ // origin
+ scene.append(
+ $('')
+ .attr('rotation', [1, 0, 0, Math.PI / 2])
+ .append(
+ $('')
+ .attr('fieldofview', 0.9)
+ .attr('position', [2 * windowScale, 0, 0])
+ .attr('orientation', [0, 1, 0, Math.PI / 2])
+ )
+ );
+
+ scene.append($('').attr('skycolor', '1 1 1'));
+
+ // draw components of scene
+ if (options.showAxes) {
+ drawAxes();
+ }
- // get some initial global configuration
- var labels = text.match(/AxesLabel\s*->\s*\{\s*(\w+),\s*(\w+),\s*(\w+)\s*\}/);
+ drawSurface();
+ drawLines();
+ drawLonePoints();
+ drawLoneLabels();
+ };
- if (labels) {
- options.axisKey = [labels[1],labels[2],labels[3]];
- }
+ var parseLive3DData = function (text) {
+ // Set up variables
+ $.each(options.vars, function (name, data) {
+ eval(name + '=' + data);
+ });
- // split the input into blocks and parse
- var blocks = recurseMathematicaBlocks(text);
-
- parseMathematicaBlocks(blocks);
-
- };
-
- // find max and min of all mesh coordinate points and
- // the maximum coordinate value for the scale.
- var setExtremum = function () {
- var min = [0,0,0];
- var max = [0,0,0];
-
- surfaceCoords.forEach(function(point) {
- for (var i=0; i< 3; i++) {
- if (point[i] < min[i]) {
- min[i] = point[i];
- } else if (point[i]>max[i]) {
- max[i] = point[i];
- }
- }
- });
-
- lineCoords.forEach(function(line) {
- for (var i=0; i<2; i++) {
- for (var j=0; j<3; j++) {
- if (line[i][j] < min[j]) {
- min[j] = line[i][j];
- } else if (line[i][j]>max[j]) {
- max[j] = line[i][j];
- }
+ // this parses axes commands.
+ if (text.match(/Axes\s*->\s*True/)) {
+ options.showAxes = true;
}
- }
- });
- coordMins = min;
- coordMaxs = max;
-
- var sum = 0;
- for (var i=0; i< 3; i++) {
- sum += max[i]-min[i];
- }
-
- windowScale = sum/3;
- };
-
- var drawLines = function() {
- if (lineCoords.length==0) {
- return;
- }
+ // get some initial global configuration
+ var labels = text.match(/AxesLabel\s*->\s*\{\s*(\w+),\s*(\w+),\s*(\w+)\s*\}/);
- // Add surface to scene as an indexedfaceset
-
- var linegroup = $('');
-
- lineCoords.forEach(function(line){
-
- // lines are cylinders that start centered at the origin
- // along the y axis. We have to translate and rotate them
- // into place
- var length = Math.sqrt(Math.pow((line[0][0]-line[1][0]),2)+
- Math.pow((line[0][1]-line[1][1]),2)+
- Math.pow((line[0][2]-line[1][2]),2));
- var rotation = [];
-
- if (length == 0) {
- return;
- }
-
- rotation[0] = (line[1][2]-line[0][2]);
- rotation[1] = 0;
- rotation[2] = (line[0][0]-line[1][0]);
- rotation[3] = Math.acos((line[1][1]-line[0][1])/length);
-
- var trans = [0,0,0];
-
- for (var i=0; i < 3; i++) {
- trans[i] = (line[1][i] + line[0][i])/2;
- }
-
- var shape = $("").appendTo($("")
- .attr('translation',trans)
- .attr('rotation',rotation)
- .appendTo(linegroup));
- var color = [0,0,0];
- var radius = .005;
-
- // line[2] contains the block index
- if (line[2] in colors) {
- color = colors[line[2]];
- }
-
- if (line[2] in lineThickness) {
- radius = Math.max(lineThickness[line[2]],.005);
- }
-
- $("").appendTo(shape)
- .append($("")
- .attr('diffusecolor',color));
-
- shape.append($("")
- .attr("height", length)
- .attr("radius", radius*2));
- });
-
- scene.append(linegroup);
- }
-
- var drawSurface = function() {
- var coordstr = '';
- var indexstr = '';
- var colorstr = '';
- var colorindstr = '';
-
- if (surfaceCoords.length == 0) {
- return;
- }
+ if (labels) {
+ options.axisKey = [labels[1], labels[2], labels[3]];
+ }
- // build a string with all the surface coodinates
- surfaceCoords.forEach(function(point) {
- coordstr += point[0]+' '+point[1]+' '+point[2]+' ';
- });
-
- // build a string with all the surface indexes
- // at the same time build a string with color data
- // and the associated color indexes
- surfaceIndex.forEach(function(index) {
- indexstr += index+' ';
-
- if (index == -1) {
- colorindstr += '-1 ';
- return;
- }
-
- var cindex = parseInt((surfaceCoords[index][2]-coordMins[2])/(coordMaxs[2]-coordMins[2])*colormap.length);
-
- if (cindex == colormap.length) {
- cindex--;
- }
-
- colorindstr += cindex+' ';
-
- });
-
- colormap.forEach(function(color) {
- for (var i=0; i<3; i++) {
- color[i] += .2;
- color[i] = Math.min(color[i],1);
- }
-
- colorstr += color[0]+' '+color[1]+' '+color[2]+' ';
- });
-
- var flatcolor = false;
- var color = [];
+ // split the input into blocks and parse
+ var blocks = recurseMathematicaBlocks(text);
- if (surfaceBlockIndex in colors) {
- flatcolor = true;
- color = colors[surfaceBlockIndex];
- }
+ parseMathematicaBlocks(blocks);
+ };
- // Add surface to scene as an indexedfaceset
- var shape = $("").appendTo(scene);
-
- var appearance = $("").appendTo(shape);
-
- appearance .append($("")
- .attr("ambientIntensity",'0')
- .attr('convex','false')
- .attr('creaseangle',Math.PI)
- .attr('diffusecolor',color)
- .attr("shininess",".015"));
-
- var indexedfaceset = $("")
- .attr('coordindex',indexstr)
- .attr('solid','false');
-
- indexedfaceset.append($("")
- .attr('point',coordstr));
-
- if (!flatcolor) {
- indexedfaceset.attr('colorindex',colorindstr);
- indexedfaceset.append($("")
- .attr('color',colorstr));
- }
+ // find max and min of all mesh coordinate points and
+ // the maximum coordinate value for the scale.
+ var setExtremum = function () {
+ var min = [0, 0, 0];
+ var max = [0, 0, 0];
- // append the indexed face set to the shape after its assembled.
- // otherwise sometimes x3d tries to access the various data before
- // its ready
- indexedfaceset.appendTo(shape);
-
- if (options.drawMesh) {
-
- shape = $("").appendTo(scene);
-
- appearance = $("").appendTo(shape);
-
- appearance .append($("")
- .attr('diffusecolor',[0,0,0]));
-
- var indexedlineset = $("")
- .attr('coordindex',indexstr)
- .attr('solid','true');
-
- indexedlineset.append($("")
- .attr('point',coordstr));
-
- indexedlineset.appendTo(shape);
- }
+ surfaceCoords.forEach(function (point) {
+ for (var i = 0; i < 3; i++) {
+ if (point[i] < min[i]) {
+ min[i] = point[i];
+ } else if (point[i] > max[i]) {
+ max[i] = point[i];
+ }
+ }
+ });
- }
-
- var drawAxes = function() {
-
- // build x axis and add the ticks.
- // all of this is done in two dimensions and then rotated and shifted
- // into place
- var xgroup = $("").appendTo($("")
- .appendTo(scene)
- .attr('translation',[0,coordMins[1],coordMins[2]]));
-
- var xaxis = $("").append($("")
- .append($("")
- .attr("emissiveColor", 'black')
- ))
- .append($("")
- .attr("lineSegments", coordMins[0]+' 0 '+coordMaxs[0]+' 0'));
- xgroup.append(xaxis);
-
- $.each(makeAxisTicks(0),function() {
- this.appendTo(xgroup)});
-
- if (options.showAxesCube) {
-
- var trans = [[0,coordMins[1],coordMaxs[2]],
- [0,coordMaxs[1],coordMins[2]],
- [0,coordMaxs[1],coordMaxs[2]]];
-
- trans.forEach(function (tran) {
- $("").attr('translation',tran)
- .appendTo(scene)
- .append($("").append($("")
- .append($("")
- .attr("emissiveColor", 'black')
- ))
- .append($("")
- .attr("lineSegments", coordMins[0]+' 0 '+coordMaxs[0]+' 0')));
- });
- }
+ lineCoords.forEach(function (line) {
+ for (var i = 0; i < 2; i++) {
+ for (var j = 0; j < 3; j++) {
+ if (line[i][j] < min[j]) {
+ min[j] = line[i][j];
+ } else if (line[i][j] > max[j]) {
+ max[j] = line[i][j];
+ }
+ }
+ }
+ });
+ coordMins = min;
+ coordMaxs = max;
- // build y axis and add the ticks
- var ygroup = $("").appendTo($("")
- .appendTo(scene)
- .attr('translation',[coordMins[0],0,coordMins[2]])
- .attr('rotation',[0,0,1,Math.PI/2]));
-
- var yaxis = $("").append($("")
- .append($("")
- .attr("emissiveColor", 'black')
- ))
- .append($("")
- .attr("lineSegments", coordMins[1]+' 0 '+coordMaxs[1]+' 0'));
- ygroup.append(yaxis);
-
- $.each(makeAxisTicks(1),function() {
- this.appendTo(ygroup)});
-
- if (options.showAxesCube) {
-
- var trans = [[coordMins[0],0,coordMaxs[2]],
- [coordMaxs[0],0,coordMins[2]],
- [coordMaxs[0],0,coordMaxs[2]]];
-
- trans.forEach(function (tran) {
- $("").attr('translation',tran)
- .attr('rotation',[0,0,1,Math.PI/2])
- .appendTo(scene)
- .append($("").append($("")
- .append($("")
- .attr("emissiveColor", 'black')
- ))
- .append($("")
- .attr("lineSegments", coordMins[1]+' 0 '+coordMaxs[1]+' 0')));
- });
- }
-
- // build z axis and add the ticks
- var zgroup = $("").appendTo($("")
- .appendTo(scene)
- .attr('translation',[coordMins[0],coordMins[1],0])
- .attr('rotation',[0,1,0,-Math.PI/2]));
-
- var zaxis = $("").append($("")
- .append($("")
- .attr("emissiveColor", 'black')
- ))
- .append($("")
- .attr("lineSegments", coordMins[2]+' 0 '+coordMaxs[2]+' 0'));
-
- zgroup.append(zaxis);
-
- $.each(makeAxisTicks(2),function() {
- this.appendTo(zgroup)});
-
- if (options.showAxesCube) {
-
- var trans = [[coordMins[0],coordMaxs[1],0],
- [coordMaxs[0],coordMins[1],0],
- [coordMaxs[0],coordMaxs[1],0]];
-
- trans.forEach(function (tran) {
- $("").attr('translation',tran)
- .attr('rotation',[0,1,0,-Math.PI/2])
- .appendTo(scene)
- .append($("").append($("")
- .append($("")
- .attr("emissiveColor", 'black')
- ))
- .append($("")
- .attr("lineSegments", coordMins[2]+' 0 '+coordMaxs[2]+' 0')));
- });
- }
-
- }
-
- // biuilds the ticks, the tick labels, and the axis label for
- // axisindex I
- var makeAxisTicks = function (I) {
- var shapes = [];
-
- for(var i=0; i").append($($("")
- .append($("")
- .attr("diffuseColor","black"))));
- tick.appendTo($("")
- .attr('translation',[coord,0,0]));
-
- tick.append($("")
- .attr('size', options.tickSize+' '
- +options.tickSize+' '+
- options.tickSize));
-
- shapes.push(tick.parent());
-
- // labels have two decimal places and always point towards view
- var ticklabel = $("").append($($("")
- .append($("")
- .attr("diffuseColor","black"))));
-
- ticklabel.appendTo($("")
- .attr("axisOfRotation", "0 0 0")
- .appendTo($("")
- .attr('translation',[coord,.1,0])));
-
- ticklabel.append($("")
- .attr('string',coord.toFixed(2))
- .attr('solid','true')
- .append($("")
- .attr('size',options.tickFontSize*windowScale)
- .attr('family', "mono")
- .attr('style', 'bold')
- .attr('justify', 'MIDDLE')));
-
- shapes.push(ticklabel.parent().parent());
+ var sum = 0;
- }
-
- // axis label goes on the end of the axis.
- var axislabel = $("").append($($("")
- .append($("")
- .attr("diffuseColor","black"))));
-
- axislabel.appendTo($("")
- .attr("axisOfRotation", "0 0 0")
- .appendTo($("")
- .attr('translation',[coordMaxs[I],.1,0])));
-
- axislabel.append($("")
- .attr('string',options.axisKey[I])
- .attr('solid','true')
- .append($("")
- .attr('size',options.tickFontSize*windowScale)
- .attr('family', "mono")
- .attr('style', 'bold')
- .attr('justify', 'MIDDLE')));
-
- shapes.push(axislabel.parent().parent());
-
- return shapes;
- }
-
- var drawLonePoints = function () {
-
- lonePoints.forEach(function (point) {
-
- var color = 'black';
- if (point.rgb) {
- color=point.rgb;
- }
-
- // lone points are drawn as spheres so they have mass
- var sphere = $("").append($($("")
- .append($("")
- .attr("diffuseColor",color))));
- sphere.appendTo($("")
- .attr('translation',point.coords));
-
- sphere.append($("")
- .attr('radius',point.radius*2.25));
-
- sphere.parent().appendTo(scene);
-
- });
-
- }
-
- var drawLoneLabels = function () {
-
- loneLabels.forEach(function (label) {
-
- // the text is a billboard that automatically faces the user
- var text = $("").append($($("")
- .append($("")
- .attr("diffuseColor",'black'))));
-
- text.appendTo($("")
- .attr("axisOfRotation", "0 0 0")
- .appendTo($("")
- .attr('translation',label.coords)));
-
- var size = '.5';
- if (label.size) {
- //mathematica label sizes are fontsizes, where
- //the units for x3dom are local coord sizes
- size = label.size/(1.5*windowScale);
- }
-
- text.append($("")
- .attr('string',label.text)
- .attr('solid','true')
- .append($("")
- .attr('size',size)
- .attr('family', "mono")
- .attr('justify', 'MIDDLE')));
-
- text.parent().parent().appendTo(scene);
-
- });
-
- }
-
- var parseMathematicaBlocks = function (blocks) {
-
- blocks.forEach(function(block) {
- blockIndex++;
-
- if (block.match(/^\s*\{/)) {
- // This is a block inside of a block.
- // so recurse
- var subblocks = recurseMathematicaBlocks(block);
- parseMathematicaBlocks(subblocks);
-
- } else if (block.match(/Point/)) {
- // now find any individual points that need to be plotted
- // points are defined by short blocks so we dont split into
- // individual commands
- var str = block.match(/Point\[\s*\{\s*(-?\d*\.?\d*)\s*,\s*(-?\d*\.?\d*)\s*,\s*(-?\d*\.?\d*)\s*\}/);
- var point = {};
-
- if (!str) {
- console.log('Error Parsing Point');
- return;
- }
-
- point.coords = [parseFloat(str[1]),parseFloat(str[2]),parseFloat(str[3])];
-
- str = block.match(/PointSize\[\s*(\d*\.?\d*)\s*\]/);
-
- if (str) {
- point.radius = parseFloat(str[1]);
+ for (var i = 0; i < 3; i++) {
+ sum += max[i] - min[i];
}
-
- str = block.match(/RGBColor\[\s*(\d*\.?\d*)\s*,\s*(\d*\.?\d*)\s*,\s*(\d*\.?\d*)\s*\]/);
-
- if (str) {
- point.rgb = [parseFloat(str[1]),parseFloat(str[2]),parseFloat(str[3])];
+
+ windowScale = sum / 3;
+ };
+
+ var drawLines = function () {
+ if (lineCoords.length == 0) {
+ return;
}
-
- lonePoints.push(point);
-
- } else {
- // Otherwise its a list of commands that we need to
- // process individually
- var commands = splitMathematicaBlocks(block);
-
- commands.forEach(function(command) {
- if (command.match(/^\s*\{/)) {
- // This is a block inside of a block.
- // so recurse
- var subblocks = recurseMathematicaBlocks(block);
- parseMathematicaBlocks(subblocks);
- } else if (command.match(/Polygon/)) {
- if (!surfaceBlockIndex) {
- surfaceBlockIndex = blockIndex;
- }
- var polystring = command.replace(/Polygon\[([^\]]*)\]/,"$1");
- var pointstrings = recurseMathematicaBlocks(polystring,-1);
- // for each polygon extract all the points
- pointstrings.forEach(function(pointstring) {
- pointstring = pointstring.replace(/\{([^\{]*)\}/,"$1");
-
- var splitstring = pointstring.split(',');
- var point = [];
-
- for (var i=0; i < 3; i++) {
- point[i] = parseFloat(eval(splitstring[i]));
- }
-
- // find the index of the point in surfaceCoords. If
- // the point is not in surfaceCoords, add it
- for (var i=0; i');
+
+ lineCoords.forEach(function (line) {
+ // lines are cylinders that start centered at the origin
+ // along the y axis. We have to translate and rotate them
+ // into place
+ var length = Math.sqrt(
+ Math.pow(line[0][0] - line[1][0], 2) +
+ Math.pow(line[0][1] - line[1][1], 2) +
+ Math.pow(line[0][2] - line[1][2], 2)
+ );
+ var rotation = [];
+
+ if (length == 0) {
return;
- }
}
- line.push(blockIndex);
+ rotation[0] = line[1][2] - line[0][2];
+ rotation[1] = 0;
+ rotation[2] = line[0][0] - line[1][0];
+ rotation[3] = Math.acos((line[1][1] - line[0][1]) / length);
- lineCoords.push(line);
+ var trans = [0, 0, 0];
- } else if (command.match(/RGBColor/)) {
- var str = command.match(/RGBColor\[\s*(\d*\.?\d*)\s*,\s*(\d*\.?\d*)\s*,\s*(\d*\.?\d*)\s*\]/);
+ for (var i = 0; i < 3; i++) {
+ trans[i] = (line[1][i] + line[0][i]) / 2;
+ }
- colors[blockIndex] = [parseFloat(str[1]),parseFloat(str[2]),parseFloat(str[3])];
+ var shape = $('').appendTo(
+ $('').attr('translation', trans).attr('rotation', rotation).appendTo(linegroup)
+ );
+ var color = [0, 0, 0];
+ var radius = 0.005;
- } else if (command.match(/Thickness/)) {
- var str = command.match(/Thickness\[\s*(\d*\.?\d*)\s*\]/);
+ // line[2] contains the block index
+ if (line[2] in colors) {
+ color = colors[line[2]];
+ }
- lineThickness[blockIndex] = parseFloat(str[1]);
-
- } else if (command.match(/Text/)) {
- // now find any individual labels that need to be plotted
- var str = command.match(/\{\s*(-?\d*\.?\d*)\s*,\s*(-?\d*\.?\d*)\s*,\s*(-?\d*\.?\d*)\s*\}/);
- var label = {};
-
- if (!str) {
- console.log('Error Parsing Label');
- return;
+ if (line[2] in lineThickness) {
+ radius = Math.max(lineThickness[line[2]], 0.005);
}
-
- label.coords = [parseFloat(str[1]),parseFloat(str[2]),parseFloat(str[3])];
- str = command.match(/StyleForm\[\s*(\w+),\s*FontSize\s*->\s*(\d+)\s*\]/);
-
- if (!str) {
- console.log('Error Parsing Label');
- return;
+
+ $('').appendTo(shape).append($('').attr('diffusecolor', color));
+
+ shape.append(
+ $('')
+ .attr('height', length)
+ .attr('radius', radius * 2)
+ );
+ });
+
+ scene.append(linegroup);
+ };
+
+ var drawSurface = function () {
+ var coordstr = '';
+ var indexstr = '';
+ var colorstr = '';
+ var colorindstr = '';
+
+ if (surfaceCoords.length == 0) {
+ return;
+ }
+
+ // build a string with all the surface coodinates
+ surfaceCoords.forEach(function (point) {
+ coordstr += point[0] + ' ' + point[1] + ' ' + point[2] + ' ';
+ });
+
+ // build a string with all the surface indexes
+ // at the same time build a string with color data
+ // and the associated color indexes
+ surfaceIndex.forEach(function (index) {
+ indexstr += index + ' ';
+
+ if (index == -1) {
+ colorindstr += '-1 ';
+ return;
+ }
+
+ var cindex = parseInt(
+ ((surfaceCoords[index][2] - coordMins[2]) / (coordMaxs[2] - coordMins[2])) * colormap.length
+ );
+
+ if (cindex == colormap.length) {
+ cindex--;
}
-
- label.text = str[1];
- label.fontSize = str[2];
-
- loneLabels.push(label);
-
- }
+
+ colorindstr += cindex + ' ';
});
-
- }
- });
- }
-
- var splitMathematicaBlocks = function (text) {
- // This splits a list of mathematica commands on the commas
-
- var bracketcount = 0;
- var blocks = [];
- var block = '';
-
- for (var i=0; i < text.length; i++) {
-
- block += text.charAt(i);
-
- if (text.charAt(i) === '[') {
- bracketcount++;
- }
-
- if (text.charAt(i) == ']') {
- bracketcount--;
- if (bracketcount == 0) {
- i++;
- blocks.push(block);
- block = '';
+
+ colormap.forEach(function (color) {
+ for (var i = 0; i < 3; i++) {
+ color[i] += 0.2;
+ color[i] = Math.min(color[i], 1);
+ }
+
+ colorstr += color[0] + ' ' + color[1] + ' ' + color[2] + ' ';
+ });
+
+ var flatcolor = false;
+ var color = [];
+
+ if (surfaceBlockIndex in colors) {
+ flatcolor = true;
+ color = colors[surfaceBlockIndex];
}
- }
- }
+ // Add surface to scene as an indexedfaceset
+ var shape = $('').appendTo(scene);
- return blocks;
- }
+ var appearance = $('').appendTo(shape);
+ appearance.append(
+ $('')
+ .attr('ambientIntensity', '0')
+ .attr('convex', 'false')
+ .attr('creaseangle', Math.PI)
+ .attr('diffusecolor', color)
+ .attr('shininess', '.015')
+ );
+ var indexedfaceset = $('').attr('coordindex', indexstr).attr('solid', 'false');
- var recurseMathematicaBlocks = function (text,initialcount) {
- // the mathematica code comes in blocks encolsed by {}
- // this code makes an array of those blocks. The largest of them will
- // be the polygon block which defines the surface.
- var bracketcount = 0;
- var blocks = [];
- var block = '';
-
- if (initialcount) {
- bracketcount = initialcount;
- }
+ indexedfaceset.append($('').attr('point', coordstr));
+
+ if (!flatcolor) {
+ indexedfaceset.attr('colorindex', colorindstr);
+ indexedfaceset.append($('').attr('color', colorstr));
+ }
- for (var i=0; i < text.length; i++) {
+ // append the indexed face set to the shape after its assembled.
+ // otherwise sometimes x3d tries to access the various data before
+ // its ready
+ indexedfaceset.appendTo(shape);
- if (text.charAt(i) === '{') {
- bracketcount++;
- }
+ if (options.drawMesh) {
+ shape = $('').appendTo(scene);
- if (bracketcount > 0) {
- block += text.charAt(i);
- }
+ appearance = $('').appendTo(shape);
- if (text.charAt(i) == '}') {
- bracketcount--;
- if (bracketcount == 0) {
- blocks.push(block.substring(1,block.length-1));
- block = '';
+ appearance.append($('').attr('diffusecolor', [0, 0, 0]));
+
+ var indexedlineset = $('').attr('coordindex', indexstr).attr('solid', 'true');
+
+ indexedlineset.append($('').attr('point', coordstr));
+
+ indexedlineset.appendTo(shape);
}
+ };
+
+ var drawAxes = function () {
+ // build x axis and add the ticks.
+ // all of this is done in two dimensions and then rotated and shifted
+ // into place
+ var xgroup = $('').appendTo(
+ $('').appendTo(scene).attr('translation', [0, coordMins[1], coordMins[2]])
+ );
+
+ var xaxis = $('')
+ .append($('').append($('').attr('emissiveColor', 'black')))
+ .append($('').attr('lineSegments', coordMins[0] + ' 0 ' + coordMaxs[0] + ' 0'));
+ xgroup.append(xaxis);
+
+ $.each(makeAxisTicks(0), function () {
+ this.appendTo(xgroup);
+ });
- }
- }
+ if (options.showAxesCube) {
+ var trans = [
+ [0, coordMins[1], coordMaxs[2]],
+ [0, coordMaxs[1], coordMins[2]],
+ [0, coordMaxs[1], coordMaxs[2]]
+ ];
+
+ trans.forEach(function (tran) {
+ $('')
+ .attr('translation', tran)
+ .appendTo(scene)
+ .append(
+ $('')
+ .append($('').append($('').attr('emissiveColor', 'black')))
+ .append($('').attr('lineSegments', coordMins[0] + ' 0 ' + coordMaxs[0] + ' 0'))
+ );
+ });
+ }
- return blocks;
- }
-
-
- // This section of code is run whenever the object is created
- // run intialize with the mathematica string, possibly getting the string
- // form an ajax call if necessary
-
- if (options.input) {
- initialize(options.input);
- } else if (options.archive) {
- // If an archive file is provided then that is the file we get
- // the file name is then the file we want inside the archive.
- JSZipUtils.getBinaryContent(options.archive, function (error, data) {
- if (error) {
- console.log(error);
- $(container).html('Failed to get input archive');
- }
-
- JSZip.loadAsync(data).then((zip) => {
- zip.file(options.file).async('string').then((string) => initialize(string));
+ // build y axis and add the ticks
+ var ygroup = $('').appendTo(
+ $('')
+ .appendTo(scene)
+ .attr('translation', [coordMins[0], 0, coordMins[2]])
+ .attr('rotation', [0, 0, 1, Math.PI / 2])
+ );
+
+ var yaxis = $('')
+ .append($('').append($('').attr('emissiveColor', 'black')))
+ .append($('').attr('lineSegments', coordMins[1] + ' 0 ' + coordMaxs[1] + ' 0'));
+ ygroup.append(yaxis);
+
+ $.each(makeAxisTicks(1), function () {
+ this.appendTo(ygroup);
});
- });
-
- } else if (options.file) {
-
- $.ajax({
- url : options.file,
- dataType : 'text',
- async : 'true',
- success : function(data) {
- initialize(data);
- },
- error : function(x,y,error) {
- console.log(error);
- $(container).html('Failed to get input file');
- }});
-
- } else {
- $(container).html('No input data provided');
- }
-}
+ if (options.showAxesCube) {
+ var trans = [
+ [coordMins[0], 0, coordMaxs[2]],
+ [coordMaxs[0], 0, coordMins[2]],
+ [coordMaxs[0], 0, coordMaxs[2]]
+ ];
+
+ trans.forEach(function (tran) {
+ $('')
+ .attr('translation', tran)
+ .attr('rotation', [0, 0, 1, Math.PI / 2])
+ .appendTo(scene)
+ .append(
+ $('')
+ .append($('').append($('').attr('emissiveColor', 'black')))
+ .append($('').attr('lineSegments', coordMins[1] + ' 0 ' + coordMaxs[1] + ' 0'))
+ );
+ });
+ }
+
+ // build z axis and add the ticks
+ var zgroup = $('').appendTo(
+ $('')
+ .appendTo(scene)
+ .attr('translation', [coordMins[0], coordMins[1], 0])
+ .attr('rotation', [0, 1, 0, -Math.PI / 2])
+ );
+
+ var zaxis = $('')
+ .append($('').append($('').attr('emissiveColor', 'black')))
+ .append($('').attr('lineSegments', coordMins[2] + ' 0 ' + coordMaxs[2] + ' 0'));
+
+ zgroup.append(zaxis);
+
+ $.each(makeAxisTicks(2), function () {
+ this.appendTo(zgroup);
+ });
+
+ if (options.showAxesCube) {
+ var trans = [
+ [coordMins[0], coordMaxs[1], 0],
+ [coordMaxs[0], coordMins[1], 0],
+ [coordMaxs[0], coordMaxs[1], 0]
+ ];
+
+ trans.forEach(function (tran) {
+ $('')
+ .attr('translation', tran)
+ .attr('rotation', [0, 1, 0, -Math.PI / 2])
+ .appendTo(scene)
+ .append(
+ $('')
+ .append($('').append($('').attr('emissiveColor', 'black')))
+ .append($('').attr('lineSegments', coordMins[2] + ' 0 ' + coordMaxs[2] + ' 0'))
+ );
+ });
+ }
+ };
+
+ // biuilds the ticks, the tick labels, and the axis label for
+ // axisindex I
+ var makeAxisTicks = function (I) {
+ var shapes = [];
+
+ for (var i = 0; i < options.numTicks - 1; i++) {
+ // coordinate of tick and label
+ var coord = ((coordMaxs[I] - coordMins[I]) / options.numTicks) * (i + 1) + coordMins[I];
+
+ //ticks are boxes defined by tickSize
+ var tick = $('').append(
+ $($('').append($('').attr('diffuseColor', 'black')))
+ );
+ tick.appendTo($('').attr('translation', [coord, 0, 0]));
+
+ tick.append($('').attr('size', options.tickSize + ' ' + options.tickSize + ' ' + options.tickSize));
+
+ shapes.push(tick.parent());
+
+ // labels have two decimal places and always point towards view
+ var ticklabel = $('').append(
+ $($('').append($('').attr('diffuseColor', 'black')))
+ );
+
+ ticklabel.appendTo(
+ $('')
+ .attr('axisOfRotation', '0 0 0')
+ .appendTo($('').attr('translation', [coord, 0.1, 0]))
+ );
+
+ ticklabel.append(
+ $('')
+ .attr('string', coord.toFixed(2))
+ .attr('solid', 'true')
+ .append(
+ $('')
+ .attr('size', options.tickFontSize * windowScale)
+ .attr('family', 'mono')
+ .attr('style', 'bold')
+ .attr('justify', 'MIDDLE')
+ )
+ );
+
+ shapes.push(ticklabel.parent().parent());
+ }
+
+ // axis label goes on the end of the axis.
+ var axislabel = $('').append(
+ $($('').append($('').attr('diffuseColor', 'black')))
+ );
+
+ axislabel.appendTo(
+ $('')
+ .attr('axisOfRotation', '0 0 0')
+ .appendTo($('').attr('translation', [coordMaxs[I], 0.1, 0]))
+ );
+
+ axislabel.append(
+ $('')
+ .attr('string', options.axisKey[I])
+ .attr('solid', 'true')
+ .append(
+ $('')
+ .attr('size', options.tickFontSize * windowScale)
+ .attr('family', 'mono')
+ .attr('style', 'bold')
+ .attr('justify', 'MIDDLE')
+ )
+ );
+
+ shapes.push(axislabel.parent().parent());
+
+ return shapes;
+ };
+
+ var drawLonePoints = function () {
+ lonePoints.forEach(function (point) {
+ var color = 'black';
+ if (point.rgb) {
+ color = point.rgb;
+ }
+
+ // lone points are drawn as spheres so they have mass
+ var sphere = $('').append(
+ $($('').append($('').attr('diffuseColor', color)))
+ );
+ sphere.appendTo($('').attr('translation', point.coords));
+
+ sphere.append($('').attr('radius', point.radius * 2.25));
+
+ sphere.parent().appendTo(scene);
+ });
+ };
+
+ var drawLoneLabels = function () {
+ loneLabels.forEach(function (label) {
+ // the text is a billboard that automatically faces the user
+ var text = $('').append(
+ $($('').append($('').attr('diffuseColor', 'black')))
+ );
+
+ text.appendTo(
+ $('')
+ .attr('axisOfRotation', '0 0 0')
+ .appendTo($('').attr('translation', label.coords))
+ );
+
+ var size = '.5';
+ if (label.size) {
+ //mathematica label sizes are fontsizes, where
+ //the units for x3dom are local coord sizes
+ size = label.size / (1.5 * windowScale);
+ }
+
+ text.append(
+ $('')
+ .attr('string', label.text)
+ .attr('solid', 'true')
+ .append($('').attr('size', size).attr('family', 'mono').attr('justify', 'MIDDLE'))
+ );
+
+ text.parent().parent().appendTo(scene);
+ });
+ };
+
+ var parseMathematicaBlocks = function (blocks) {
+ blocks.forEach(function (block) {
+ blockIndex++;
+
+ if (block.match(/^\s*\{/)) {
+ // This is a block inside of a block.
+ // so recurse
+ var subblocks = recurseMathematicaBlocks(block);
+ parseMathematicaBlocks(subblocks);
+ } else if (block.match(/Point/)) {
+ // now find any individual points that need to be plotted
+ // points are defined by short blocks so we dont split into
+ // individual commands
+ var str = block.match(/Point\[\s*\{\s*(-?\d*\.?\d*)\s*,\s*(-?\d*\.?\d*)\s*,\s*(-?\d*\.?\d*)\s*\}/);
+ var point = {};
+
+ if (!str) {
+ console.log('Error Parsing Point');
+ return;
+ }
+
+ point.coords = [parseFloat(str[1]), parseFloat(str[2]), parseFloat(str[3])];
+
+ str = block.match(/PointSize\[\s*(\d*\.?\d*)\s*\]/);
+
+ if (str) {
+ point.radius = parseFloat(str[1]);
+ }
+
+ str = block.match(/RGBColor\[\s*(\d*\.?\d*)\s*,\s*(\d*\.?\d*)\s*,\s*(\d*\.?\d*)\s*\]/);
+
+ if (str) {
+ point.rgb = [parseFloat(str[1]), parseFloat(str[2]), parseFloat(str[3])];
+ }
+
+ lonePoints.push(point);
+ } else {
+ // Otherwise its a list of commands that we need to
+ // process individually
+ var commands = splitMathematicaBlocks(block);
+
+ commands.forEach(function (command) {
+ if (command.match(/^\s*\{/)) {
+ // This is a block inside of a block.
+ // so recurse
+ var subblocks = recurseMathematicaBlocks(block);
+ parseMathematicaBlocks(subblocks);
+ } else if (command.match(/Polygon/)) {
+ if (!surfaceBlockIndex) {
+ surfaceBlockIndex = blockIndex;
+ }
+
+ var polystring = command.replace(/Polygon\[([^\]]*)\]/, '$1');
+ var pointstrings = recurseMathematicaBlocks(polystring, -1);
+ // for each polygon extract all the points
+ pointstrings.forEach(function (pointstring) {
+ pointstring = pointstring.replace(/\{([^\{]*)\}/, '$1');
+
+ var splitstring = pointstring.split(',');
+ var point = [];
+
+ for (var i = 0; i < 3; i++) {
+ point[i] = parseFloat(eval(splitstring[i]));
+ }
+
+ // find the index of the point in surfaceCoords. If
+ // the point is not in surfaceCoords, add it
+ for (var i = 0; i < surfaceCoords.length; i++) {
+ if (
+ surfaceCoords[i][0] == point[0] &&
+ surfaceCoords[i][1] == point[1] &&
+ surfaceCoords[i][2] == point[2]
+ ) {
+ surfaceIndex.push(i);
+
+ return;
+ }
+ }
+
+ surfaceIndex.push(surfaceCoords.length);
+ surfaceCoords.push(point);
+ });
+
+ surfaceIndex.push(-1);
+ } else if (command.match(/Line/)) {
+ //Add a line to the line array
+
+ var str = command.replace(/Line\[([^\]]*)\],/, '$1');
+
+ var pointstrings = recurseMathematicaBlocks(str, -1);
+
+ var line = [];
+
+ for (var i = 0; i < 2; i++) {
+ pointstrings[i] = pointstrings[i].replace(/\{([^\{]*)\}/, '$1');
+ var splitstring = pointstrings[i].split(',');
+ var point = [];
+
+ for (var j = 0; j < 3; j++) {
+ point[j] = parseFloat(eval(splitstring[j]));
+ }
+
+ if (point) {
+ line.push(point);
+ } else {
+ console.log('Error Parsing Line');
+ return;
+ }
+ }
+
+ line.push(blockIndex);
+
+ lineCoords.push(line);
+ } else if (command.match(/RGBColor/)) {
+ var str = command.match(/RGBColor\[\s*(\d*\.?\d*)\s*,\s*(\d*\.?\d*)\s*,\s*(\d*\.?\d*)\s*\]/);
+
+ colors[blockIndex] = [parseFloat(str[1]), parseFloat(str[2]), parseFloat(str[3])];
+ } else if (command.match(/Thickness/)) {
+ var str = command.match(/Thickness\[\s*(\d*\.?\d*)\s*\]/);
+
+ lineThickness[blockIndex] = parseFloat(str[1]);
+ } else if (command.match(/Text/)) {
+ // now find any individual labels that need to be plotted
+ var str = command.match(/\{\s*(-?\d*\.?\d*)\s*,\s*(-?\d*\.?\d*)\s*,\s*(-?\d*\.?\d*)\s*\}/);
+ var label = {};
+
+ if (!str) {
+ console.log('Error Parsing Label');
+ return;
+ }
+
+ label.coords = [parseFloat(str[1]), parseFloat(str[2]), parseFloat(str[3])];
+ str = command.match(/StyleForm\[\s*(\w+),\s*FontSize\s*->\s*(\d+)\s*\]/);
+
+ if (!str) {
+ console.log('Error Parsing Label');
+ return;
+ }
+
+ label.text = str[1];
+ label.fontSize = str[2];
+
+ loneLabels.push(label);
+ }
+ });
+ }
+ });
+ };
+
+ var splitMathematicaBlocks = function (text) {
+ // This splits a list of mathematica commands on the commas
+
+ var bracketcount = 0;
+ var blocks = [];
+ var block = '';
+
+ for (var i = 0; i < text.length; i++) {
+ block += text.charAt(i);
+
+ if (text.charAt(i) === '[') {
+ bracketcount++;
+ }
+
+ if (text.charAt(i) == ']') {
+ bracketcount--;
+ if (bracketcount == 0) {
+ i++;
+ blocks.push(block);
+ block = '';
+ }
+ }
+ }
+
+ return blocks;
+ };
+
+ var recurseMathematicaBlocks = function (text, initialcount) {
+ // the mathematica code comes in blocks encolsed by {}
+ // this code makes an array of those blocks. The largest of them will
+ // be the polygon block which defines the surface.
+ var bracketcount = 0;
+ var blocks = [];
+ var block = '';
+
+ if (initialcount) {
+ bracketcount = initialcount;
+ }
+
+ for (var i = 0; i < text.length; i++) {
+ if (text.charAt(i) === '{') {
+ bracketcount++;
+ }
+
+ if (bracketcount > 0) {
+ block += text.charAt(i);
+ }
+
+ if (text.charAt(i) == '}') {
+ bracketcount--;
+ if (bracketcount == 0) {
+ blocks.push(block.substring(1, block.length - 1));
+ block = '';
+ }
+ }
+ }
+
+ return blocks;
+ };
+
+ // This section of code is run whenever the object is created
+ // run intialize with the mathematica string, possibly getting the string
+ // form an ajax call if necessary
+
+ if (options.input) {
+ initialize(options.input);
+ } else if (options.archive) {
+ // If an archive file is provided then that is the file we get
+ // the file name is then the file we want inside the archive.
+ JSZipUtils.getBinaryContent(options.archive, function (error, data) {
+ if (error) {
+ console.log(error);
+ $(container).html('Failed to get input archive');
+ }
+
+ JSZip.loadAsync(data).then((zip) => {
+ zip.file(options.file)
+ .async('string')
+ .then((string) => initialize(string));
+ });
+ });
+ } else if (options.file) {
+ $.ajax({
+ url: options.file,
+ dataType: 'text',
+ async: 'true',
+ success: function (data) {
+ initialize(data);
+ },
+ error: function (x, y, error) {
+ console.log(error);
+ $(container).html('Failed to get input file');
+ }
+ });
+ } else {
+ $(container).html('No input data provided');
+ }
+};
diff --git a/htdocs/js/MathQuill/mqeditor.js b/htdocs/js/MathQuill/mqeditor.js
index 57ad5fa0e1..8c313a79f9 100644
--- a/htdocs/js/MathQuill/mqeditor.js
+++ b/htdocs/js/MathQuill/mqeditor.js
@@ -31,6 +31,14 @@
input.classList.add('mq-edit');
answerQuill.latexInput = mq_input;
+ // Give the mathquill answer box the correct/incorrect colors.
+ if (input.classList.contains('correct')) answerQuill.classList.add('correct');
+ if (input.classList.contains('incorrect')) answerQuill.classList.add('incorrect');
+ if (input.classList.contains('partially-correct')) answerQuill.classList.add('partially-correct');
+
+ const ariaDescribedBy = input.getAttribute('aria-describedby');
+ if (ariaDescribedBy) answerQuill.setAttribute('aria-describedby', ariaDescribedBy);
+
// Default options.
const cfgOptions = {
spaceBehavesLikeTab: true,
@@ -130,8 +138,8 @@
button.append(icon);
// Find the preview button container, and add the equation editor button to that.
- const buttonContainer = container.nextElementSibling;
- if (buttonContainer && buttonContainer.classList.contains('latexentry-button-container')) {
+ const buttonContainer = document.getElementById(`${answerLabel}-latexentry-button-container`);
+ if (buttonContainer) {
buttonContainer.classList.add('d-flex', 'gap-1');
buttonContainer.prepend(button);
innerContainer.append(buttonContainer);
@@ -494,26 +502,6 @@
answerQuill.mathField.latex(answerQuill.latexInput.value);
answerQuill.mathField.moveToLeftEnd();
answerQuill.mathField.blur();
-
- // Look for a result in the attempts table for this answer.
- for (const tableLink of document.querySelectorAll('td a[data-answer-id]')) {
- // Give the mathquill answer box the correct/incorrect colors.
- if (answerLabel.includes(tableLink.dataset.answerId)) {
- if (tableLink.parentNode.classList.contains('ResultsWithoutError'))
- answerQuill.classList.add('correct');
- else {
- if (answerQuill.input.value !== '') answerQuill.classList.add('incorrect');
- }
- }
-
- // Make a click on the results table link give focus to the mathquill answer box.
- if (answerLabel === tableLink.dataset.answerId) {
- tableLink.addEventListener('click', (e) => {
- e.preventDefault();
- answerQuill.textarea.focus();
- });
- }
- }
};
// Set up MathQuill inputs that are already in the page.
diff --git a/htdocs/js/MathQuill/mqeditor.scss b/htdocs/js/MathQuill/mqeditor.scss
index ec2f517c38..e452eba03b 100644
--- a/htdocs/js/MathQuill/mqeditor.scss
+++ b/htdocs/js/MathQuill/mqeditor.scss
@@ -3,27 +3,11 @@
span[id^='mq-answer'] {
/*rtl:ignore*/
direction: ltr;
- padding: 4px 5px 2px 5px;
+ padding: 4px;
border-radius: 4px !important;
background-color: white;
margin-right: 0;
margin-left: 0;
-
- &.correct {
- border-color: rgba(81, 153, 81, 0.8);
- outline: 0;
- outline: thin dotted \9;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(81, 153, 81, 0.6);
- color: inherit;
- }
-
- &.incorrect {
- border-color: rgba(191, 84, 84, 0.8);
- outline: 0;
- outline: thin dotted \9;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(191, 84, 84, 0.6);
- color: inherit;
- }
}
input[type='text'].codeshard.mq-edit {
diff --git a/htdocs/js/Problem/problem.scss b/htdocs/js/Problem/problem.scss
index 20c10cf4b2..b2ee8ea366 100644
--- a/htdocs/js/Problem/problem.scss
+++ b/htdocs/js/Problem/problem.scss
@@ -33,13 +33,18 @@
}
/* Problem elements */
- label, input[type=text], select, textarea {
+ label,
+ input[type='text'],
+ select,
+ textarea {
font-weight: normal;
line-height: 18px;
width: auto;
}
- select, textarea, input[type=text] {
+ select,
+ textarea,
+ input[type='text'] {
display: inline-block;
padding: 4px 6px;
margin-bottom: 0;
@@ -50,56 +55,51 @@
background-color: white;
}
- textarea, input[type=text] {
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ textarea,
+ input[type='text'] {
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
- input[type=text] {
+ input[type='text'] {
height: 30px;
font-size: 14px;
line-height: 20px;
}
- select, input[type=text], input[type=radio], input[type=checkbox] {
- &.correct {
- border-color: rgba(81, 153, 81, 0.8); /* green */
+ select,
+ input[type='text'],
+ input[type='radio'],
+ input[type='checkbox'],
+ span[id^='mq-answer'],
+ .graphtool-container {
+ &.correct:not(:focus):not(.mq-focused) {
+ border-color: rgba(81, 153, 81, 1); /* green */
outline: 0;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px 2px rgba(81, 153, 81, 0.6);
- color: inherit;
+ box-shadow: inset 0 0 2px 1px rgba(0, 0, 0, 0.25), 0 0 8px 2px rgba(81, 153, 81, 1);
}
- &.incorrect {
- border-color: rgba(191, 84, 84, 0.8); /* red */
+ &.incorrect:not(:focus):not(.mq-focused) {
+ border-color: rgba(191, 84, 84, 1); /* red */
outline: 0;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px 2px rgba(191, 84, 84, 0.6);
- color:inherit;
+ box-shadow: inset 0 0 2px 1px rgba(0, 0, 0, 0.25), 0 0 8px 2px rgba(191, 84, 84, 1);
}
- }
- input[type=text], span.mq-editable-field {
- background-size: 20px auto;
- background-position: right 4px center;
- background-repeat: no-repeat;
-
- &.correct {
- padding-right: 29px;
- background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
- }
-
- &.incorrect {
- padding-right: 29px;
- background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23AE5757'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23AE5757' stroke='none'/%3e%3c/svg%3e");
+ &.partially-correct:not(:focus):not(.mq-focused) {
+ border-color: rgba(255, 193, 7, 1); /* yellow */
+ outline: 0;
+ box-shadow: inset 0 0 2px 1px rgba(0, 0, 0, 0.25), 0 0 8px 2px rgba(255, 193, 7, 1);
}
}
- input[type=radio] {
+ input[type='radio'] {
margin-right: 0.25rem;
}
select {
cursor: pointer;
- &[multiple], &[size] {
+ &[multiple],
+ &[size] {
height: auto;
}
}
@@ -108,7 +108,10 @@
max-width: 100%;
}
- input[type=text], input[type=radio], textarea, select {
+ input[type='text'],
+ input[type='radio'],
+ textarea,
+ select {
&:focus {
border-color: rgba(82, 168, 236, 0.8);
outline: 0;
@@ -118,154 +121,163 @@
.pg-table {
text-align: center;
- thead, tbody, tfoot, tr, td, th {
+ thead,
+ tbody,
+ tfoot,
+ tr,
+ td,
+ th {
padding: 0.25rem;
border: 1px solid black;
}
}
-}
-/* rtl:raw:
-.problem-content[dir=ltr] input[type=radio] {
- margin-right: 0.25rem;
-}
-*/
+ .ww-feedback-btn {
+ width: 25px;
+ line-height: 1;
+ position: relative;
+ --bs-btn-padding-x: 2px;
+ --bs-btn-padding-y: 2px;
+
+ i {
+ &::before {
+ content: url("data:image/svg+xml,");
+ }
+
+ &.correct::before {
+ content: url("data:image/svg+xml,");
+ }
+
+ &.incorrect::before {
+ content: url("data:image/svg+xml,");
+ }
+
+ &.partially-correct::before {
+ content: url("data:image/svg+xml,");
+ }
+ }
-/* Answer template */
+ &.with-message::before {
+ content: ' ';
+ position: absolute;
+ transform: translate(-50%, -50%);
+ top: 0;
+ left: 100%;
+ border: 1px solid black;
+ border-radius: 50%;
+ background-color: #dc3545;
+ padding: 0.25rem;
+ }
+ }
-.attemptResultsHeader {
- margin-bottom: 0.5rem;
- padding: 0;
- font-size: 1.4875rem;
- font-weight: bold;
- line-height: 1.2;
-}
+ .radio-buttons-container,
+ .checkboxes-container,
+ .applet-container,
+ .graphtool-outer-container,
+ .ww-feedback-container {
+ position: relative;
+ width: fit-content;
+
+ .ww-feedback-btn {
+ position: absolute;
+ left: 100%;
+ top: 0;
+ margin-left: 0.25rem;
+ }
-table.attemptResults {
- border-style: outset;
- border-width: 1px;
- margin-bottom: 1em;
- border-spacing: 1px;
- width: 100%;
- border: 1px solid #ddd;
- border-collapse: separate;
- border-radius: 4px;
+ &.align-middle {
+ .ww-feedback-btn {
+ top: 50%;
+ transform: translateY(-50%);
+ }
+ }
- thead:first-child tr:first-child > th:first-child,
- tbody:first-child tr:first-child > td:first-child,
- tbody:first-child tr:first-child > th:first-child {
- border-top-left-radius: 4px;
+ &.align-bottom {
+ .ww-feedback-btn {
+ top: unset;
+ bottom: 0;
+ }
+ }
}
+}
- thead:first-child tr:first-child > th:last-child,
- tbody:first-child tr:first-child > td:last-child,
- tbody:first-child tr:first-child > th:last-child {
- border-top-right-radius: 4px;
- }
+/* rtl:raw:
+.problem-content[dir=ltr] input[type=radio] {
+ margin-right: 0.25rem;
+}
+*/
- thead:last-child tr:last-child > th:first-child,
- tbody:last-child tr:last-child > td:first-child,
- tbody:last-child tr:last-child > th:first-child,
- tfoot:last-child tr:last-child > td:first-child,
- tfoot:last-child tr:last-child > th:first-child {
- border-bottom-left-radius: 4px;
- }
+/* Feedback */
- thead:last-child tr:last-child > th:last-child,
- tbody:last-child tr:last-child > td:last-child,
- tbody:last-child tr:last-child > th:last-child,
- tfoot:last-child tr:last-child > td:last-child,
- tfoot:last-child tr:last-child > th:last-child {
- border-bottom-right-radius: 4px;
- }
+.ww-feedback-popover {
+ --bs-popover-body-padding-x: 0;
+ --bs-popover-body-padding-y: 0;
+ --bs-popover-max-width: 600px;
+ --bs-popover-zindex: 18;
- td, th {
- border-style: inset;
- border-width: 1px;
+ .popover-header {
text-align: center;
- vertical-align: middle;
- padding: 2px 5px;
- color: inherit;
- border-color: #ddd;
- background-color: #ddd;
}
- .ArrayLayout {
- td {
- border-style: none;
- border-width: 0px;
- padding: 0px;
- background-color: transparent;
+ &.correct {
+ .popover-header {
+ --bs-popover-header-bg: var(--bs-success);
+ --bs-popover-header-color: white;
+ cursor: pointer;
}
}
- .parsehilight {
- color: inherit;
- background-color: yellow;
- }
-
- .popover {
- max-width: 100%;
- }
-
- td {
- &.FeedbackMessage {
- background-color: #ede275; /* Harvest Gold */
- }
-
- &.ResultsWithoutError {
- background-color: #8f8;
- }
-
- &.ResultsWithError {
- background-color: #d69191; /* Light Red */
- color: black;
+ &.incorrect {
+ .popover-header {
+ --bs-popover-header-bg: var(--bs-danger);
+ --bs-popover-header-color: white;
}
}
- div.answer-preview,
- span.answer-preview {
- display: block;
- width: 100%;
- height: 100%;
- }
-
- a, a span {
- color: #038;
- text-decoration: none;
-
- &:hover {
- text-decoration: underline;
+ &.partially-correct {
+ .popover-header {
+ --bs-popover-header-bg: var(--bs-warning);
}
}
-}
-
-div, label, span {
- &.ResultsWithoutError {
- color: #0f5132; /* Dark Green */
- background-color: #8f8; /* Light Green */
- padding: 0.25rem;
- border: 1px solid transparent;
- border-radius: 0.25rem;
- box-shadow: 3px 3px 3px darkgray;
- }
- &.ResultsWithError {
- color: #400; /* Dark Red */
- background-color: #d69191; /* Light Red */
- padding: 0.25rem;
- border: 1px solid transparent;
- border-radius: 0.25rem;
- box-shadow: 3px 3px 3px darkgray;
- }
-
- &.ResultsAlert {
- color: #0e038c; /* Dark Blue */
- background-color: #fbd2b8; /* Light Orange */
- padding: 0.25rem;
- border: 1px solid transparent;
- border-radius: 0.25rem;
- box-shadow: 3px 3px 3px darkgray;
+ .popover-body {
+ .card {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ --bs-card-spacer-y: 0.5rem;
+ --bs-card-cap-bg: #ddd;
+
+ .card-header {
+ border-radius: 0;
+
+ &:not(:first-child) {
+ border-top: var(--bs-card-border-width) solid var(--bs-card-border-color);
+ }
+ }
+
+ .card-body {
+ mjx-container {
+ margin: 0;
+ }
+
+ .parsehilight {
+ background-color: yellow;
+ }
+
+ .ArrayLayout {
+ td {
+ border-style: none;
+ border-width: 0px;
+ padding: 0px;
+ background-color: transparent;
+ }
+ }
+
+ &.feedback-message {
+ background-color: #ede275;
+ }
+ }
+ }
}
}
diff --git a/htdocs/js/RadioMultiAnswer/RadioMultiAnswer.scss b/htdocs/js/RadioMultiAnswer/RadioMultiAnswer.scss
index 6d6d23d3c0..9694f6547f 100644
--- a/htdocs/js/RadioMultiAnswer/RadioMultiAnswer.scss
+++ b/htdocs/js/RadioMultiAnswer/RadioMultiAnswer.scss
@@ -13,33 +13,52 @@
// # Artistic License for more details.
// ################################################################################
-.radio-container {
- display: flex;
- align-items: baseline;
-
- .radio-content {
- display: inline-block;
- margin-left: 5px;
- line-height: 26px;
- }
+.radio-multianswer-container {
+ position: relative;
+ width: fit-content;
+ max-width: calc(100% - 1rem - 25px);
- input[type='radio'] {
- flex-shrink: 0;
- margin-left: 0;
- line-height: 26px;
- align-self: first baseline;
- }
+ .radio-container {
+ display: flex;
+ align-items: baseline;
+ position: relative;
+ width: fit-content;
- label {
- flex-shrink: 0;
- line-height: 26px;
- }
+ .radio-content {
+ display: inline-block;
+ margin-left: 5px;
+ line-height: 26px;
+ }
+
+ input[type='radio'] {
+ flex-shrink: 0;
+ margin-left: 0;
+ line-height: 26px;
+ align-self: first baseline;
+ }
+
+ label {
+ flex-shrink: 0;
+ line-height: 26px;
+ }
+
+ input[disabled] {
+ pointer-events: none;
+ }
+
+ .rma-state-disabled {
+ opacity: 0.35;
+ }
- input[disabled] {
- pointer-events: none;
+ .ww-feedback-btn {
+ top: 50%;
+ transform: translateY(-50%);
+ }
}
- .rma-state-disabled {
- opacity: 0.35;
+ .ww-feedback-btn {
+ position: absolute;
+ left: 100%;
+ top: 0;
}
}
diff --git a/htdocs/js/Scaffold/scaffold.js b/htdocs/js/Scaffold/scaffold.js
index d36b986291..060c00747b 100644
--- a/htdocs/js/Scaffold/scaffold.js
+++ b/htdocs/js/Scaffold/scaffold.js
@@ -4,12 +4,19 @@
section.addEventListener('shown.bs.collapse', () => {
// Reflow MathQuill answer boxes so that their contents are rendered correctly
if (window.answerQuills) {
- Object.keys(answerQuills).forEach(
- (quill) => { if (section.querySelector('#' + quill)) answerQuills[quill].mathField.reflow(); }
- );
+ Object.keys(answerQuills).forEach((quill) => {
+ if (section.querySelector('#' + quill)) answerQuills[quill].mathField.reflow();
+ });
}
});
- })
+
+ section.addEventListener('hide.bs.collapse', () => {
+ // Close any open feedback popovers in this scaffold.
+ for (const button of section.querySelectorAll('.ww-feedback-btn')) {
+ bootstrap.Popover.getInstance(button)?.hide();
+ }
+ });
+ });
};
// Set up any scaffolds already on the page.
diff --git a/lib/Applet.pm b/lib/Applet.pm
index ecdad095f6..cb65230a19 100644
--- a/lib/Applet.pm
+++ b/lib/Applet.pm
@@ -524,7 +524,11 @@ sub insertObject {
my $objectText = $self->{objectText};
$objectText =~ s/(\$\w+)/$1/gee;
- return $objectText;
+ return
+ qq{
'
+ . $objectText
+ . '
';
}
# These methods are defined so that they can be used in the derived objects in the AppletObjects.pl macro file.
diff --git a/lib/DragNDrop.pm b/lib/DragNDrop.pm
index 3bcf18c084..7fede69171 100644
--- a/lib/DragNDrop.pm
+++ b/lib/DragNDrop.pm
@@ -160,7 +160,8 @@ sub HTML {
$out .= qq{ data-label-format="$self->{bucketLabelFormat}"} if $self->{bucketLabelFormat};
$out .= '>';
- $out .= '
';
+ $out .= '
};
$out .= qq{};
$out .= qq{}
if ($self->{allowNewBuckets});
diff --git a/lib/PGcore.pm b/lib/PGcore.pm
index 130639db9a..d5fe2c5195 100755
--- a/lib/PGcore.pm
+++ b/lib/PGcore.pm
@@ -97,6 +97,7 @@ sub new {
PG_alias => undef,
PG_problem_grader => undef,
displayMode => undef,
+ content_post_processors => [],
envir => $envir,
WARNING_messages => [],
DEBUG_messages => [],
@@ -561,6 +562,12 @@ sub get_persistent_data {
return $self->{PERSISTENCE_HASH}{$label};
}
+sub add_content_post_processor {
+ my ($self, $handler) = @_;
+ push(@{ $self->{content_post_processors} }, $handler) if ref($handler) eq 'CODE';
+ return;
+}
+
sub check_answer_hash {
my $self = shift;
foreach my $key (keys %{ $self->{PG_ANSWERS_HASH} }) {
diff --git a/lib/Value/AnswerChecker.pm b/lib/Value/AnswerChecker.pm
index 7abbda7099..b845c3b7be 100644
--- a/lib/Value/AnswerChecker.pm
+++ b/lib/Value/AnswerChecker.pm
@@ -490,7 +490,14 @@ sub ans_matrix {
}
push(@array, [@row]);
}
- $self->format_matrix([@array], open => $open, close => $close, sep => $sep, top_labels => $toplabels);
+ $self->format_matrix(
+ [@array],
+ open => $open,
+ close => $close,
+ sep => $sep,
+ top_labels => $toplabels,
+ ans_last_name => ANS_NAME($ename, $rows - 1, $cols - 1)
+ );
}
sub ANS_NAME {
@@ -599,7 +606,13 @@ sub format_matrix_HTML {
. $close
. '';
}
- return '' . $HTML . '';
+ return ''
+ . $HTML
+ . '';
}
sub EVALUATE {
diff --git a/lib/WeBWorK/PG.pm b/lib/WeBWorK/PG.pm
index bf9561914c..c34153e1a2 100644
--- a/lib/WeBWorK/PG.pm
+++ b/lib/WeBWorK/PG.pm
@@ -140,7 +140,7 @@ sub new_helper ($invocant, %options) {
}
}
- $translator->translate();
+ $translator->translate;
# IMPORTANT: The translator environment should not be trusted after the problem code runs.
@@ -173,15 +173,25 @@ sub new_helper ($invocant, %options) {
);
}
- # HTML_dpng uses an ImageGenerator. We have to render the queued equations.
+ # HTML_dpng uses an ImageGenerator. We have to render the queued equations. This must be done before the post
+ # processing, since the image tags output by the image generator initially include markers which are invalid html.
+ # Mojo::DOM will change these markers into attributes with values and this will fail.
if ($image_generator) {
- my $sourceFile = "$options{templateDirectory}$options{sourceFilePath}";
$image_generator->render(
refresh => $options{refreshMath2img} // 0,
body_text => $translator->r_text,
);
}
+ $translator->post_process_content if ref($translator->{rh_pgcore}) eq 'PGcore';
+ $translator->stringify_answers;
+
+ # Add the result summary set in post processing into the result.
+ $result->{summary} = $translator->{rh_pgcore}{result_summary}
+ if ref($translator->{rh_pgcore}) eq 'PGcore'
+ && $translator->{rh_pgcore}{result_summary}
+ && (!defined $result->{summary} || $result->{summary} !~ /\S/);
+
return bless {
translator => $translator,
head_text => ${ $translator->r_header },
@@ -245,6 +255,15 @@ sub defineProblemEnvironment ($pg_envir, $options = {}, $image_generator = undef
isInstructor => $options->{isInstructor} // 0,
PERSISTENCE_HASH => $options->{PERSISTENCE_HASH} // {},
+ # Attempt Results
+ showFeedback => $options->{showFeedback} // 0,
+ showAttemptAnswers => $options->{showAttemptAnswers} // 1,
+ showAttemptPreviews => $options->{showAttemptPreviews} // 1,
+ forceShowAttemptResults => $options->{forceShowAttemptResults} // 0,
+ showAttemptResults => $options->{showAttemptResults} // 0,
+ showMessages => $options->{showMessages} // 1,
+ showCorrectAnswers => $options->{showCorrectAnswers} // 0,
+
# The next has marks what data was updated and needs to be saved
# by the front end.
PERSISTENCE_HASH_UPDATED => {},
@@ -460,6 +479,44 @@ This may contain the following keys (example values are shown)
useBaseTenLog: 0
defaultDisplayMatrixStyle: '[s]' # left delimiter, middle line delimiters, right delimiter
+=item showFeedback (boolean, default: 0)
+
+Determines if feedback will be shown for answers in the problem. Note that
+feedback will be shown if forceShowAttemptResults is true regardless of
+the value of this option.
+
+=item showAttemptAnswers (boolean, default: 1)
+
+Determines if the student's evaluated (i.e. "Entered") answers will be shown in feedback.
+
+=item showAttemptPreviews (boolean, default: 1)
+
+Determines if the student's answer previews will be shown in feedback.
+
+=item showAttemptResults (boolean, default: 0)
+
+Determines if attempt results will be revealed in feedback. In other words,
+if the student's answers are correct, incorrect, or partially correct. This
+honors the value of the PG C flag. If that flag is
+false, then attempt results will still not be shown.
+
+If this is true, then a summary of results will also be generated. The
+summary will be returned in the C key of the C hash.
+
+=item forceShowAttemptResults (boolean, default: 0)
+
+If this is true then feedback will be shown with attempt results. This ignores
+the PG C flag and shows attempt results in any case.
+The summary will also be generated if this is true.
+
+=item showMessages (boolean, default: 1)
+
+Determines if any messages generated in answer evaluation will be shown.
+
+=item showCorrectAnswers (boolean, default: 0)
+
+Determines if correct answers will be shown.
+
=item answerPrefix (string, default: '')
A prefix to prepend to all answer labels. Note that other prefixes may be
diff --git a/lib/WeBWorK/PG/ImageGenerator.pm b/lib/WeBWorK/PG/ImageGenerator.pm
index 1bb134e62c..7354cdf030 100644
--- a/lib/WeBWorK/PG/ImageGenerator.pm
+++ b/lib/WeBWorK/PG/ImageGenerator.pm
@@ -477,7 +477,7 @@ sub fix_markers ($self) {
my %depths = %{ $self->{depths} };
for my $depthkey (keys %depths) {
if ($depths{$depthkey} eq 'none') {
- ${ $self->{body_text} } =~ s/MaRkEr$depthkey/style="vertical-align:"$self->{dvipng_align}"/g;
+ ${ $self->{body_text} } =~ s/MaRkEr$depthkey/style="vertical-align:$self->{dvipng_align}"/g;
} else {
my $ndepth = 0 - $depths{$depthkey};
${ $self->{body_text} } =~ s/MaRkEr$depthkey/style="vertical-align:${ndepth}px"/g;
diff --git a/lib/WeBWorK/PG/Localize/cs-CZ.po b/lib/WeBWorK/PG/Localize/cs-CZ.po
index 7219134a23..6cebc8f7f9 100644
--- a/lib/WeBWorK/PG/Localize/cs-CZ.po
+++ b/lib/WeBWorK/PG/Localize/cs-CZ.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:00-0500\n"
+"PO-Revision-Date: 2023-10-05 06:42-0500\n"
"Last-Translator: Robert Mařík , 2022-2023\n"
"Language-Team: Czech (Czech Republic) (http://app.transifex.com/webwork/"
"webwork2/language/cs_CZ/)\n"
@@ -19,7 +19,43 @@ msgstr ""
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n "
"<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% správně"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr "Nebylo odpovězeno na %quant(%1,otázku,otázky)."
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr "Správná odpověď"
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -42,12 +78,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr "Nápověda:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -55,21 +91,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr "Zpráva"
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr "Poznámka:"
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr "Řešení:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -77,11 +130,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -89,10 +172,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr "Zatím nehodnoceno"
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "Za částečné zodpovězení této úlohy můžete obdržet částečné hodnocení."
@@ -105,7 +196,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -113,12 +204,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -139,15 +230,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/de.po b/lib/WeBWorK/PG/Localize/de.po
index cf575cd3a6..50191e5f9f 100644
--- a/lib/WeBWorK/PG/Localize/de.po
+++ b/lib/WeBWorK/PG/Localize/de.po
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:01-0500\n"
+"PO-Revision-Date: 2023-10-05 06:42-0500\n"
"Last-Translator: Fabian Gabel, 2022\n"
"Language-Team: German (http://app.transifex.com/webwork/webwork2/language/"
"de/)\n"
@@ -21,7 +21,43 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% richtig"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr "%quant(%1,Frage wurde,Fragen wurden) nicht beantwortet."
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "Richtig"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr "Lösung"
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -44,12 +80,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr "Hinweis: "
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr "Hinweis: "
@@ -57,21 +93,38 @@ msgstr "Hinweis: "
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr "Falsch"
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr "Fehlermeldung"
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr "Note:"
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr "Lösung:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr "Lösung: "
@@ -79,11 +132,41 @@ msgstr "Lösung: "
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr "Dies is eine neu randomisierte Version der Aufgabe."
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -91,10 +174,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr "Diese Aufgabe besteht aus mehreren Teilen."
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "Für diese Aufgabe können Sie Teilpunkte erhalten."
@@ -109,7 +200,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr "Antworten können im nächsten Teil nicht mehr geändert werden!"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -117,12 +208,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr "Antwort"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr "Spalte"
@@ -143,15 +234,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr "Aufgabe"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/el.po b/lib/WeBWorK/PG/Localize/el.po
index 29a810ac2e..b6973a6208 100644
--- a/lib/WeBWorK/PG/Localize/el.po
+++ b/lib/WeBWorK/PG/Localize/el.po
@@ -34,7 +34,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:01-0500\n"
+"PO-Revision-Date: 2023-10-05 06:43-0500\n"
"Last-Translator: Kyriaki Kourouni, 2022-2023\n"
"Language-Team: Greek (http://app.transifex.com/webwork/webwork2/language/"
"el/)\n"
@@ -44,7 +44,44 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% σωστό"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr ""
+"%quant(%1,των ερωτήσεων απομένει, των ερωτήσεων απομένουν) αναπάντητες."
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "Διόρθωση"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr "Διόρθωση Απάντησης"
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr "Λάθος"
@@ -67,12 +104,12 @@ msgstr "Μετάβαση στο επόμενο"
msgid "Hardcopy will always print the original version of the problem."
msgstr "Στην έντυπη μορφή εμφανίζεται πάντα η αρχική μορφή του προβλήματος."
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr "Υπόδειξη:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr "Υπόδειξη:"
@@ -80,21 +117,38 @@ msgstr "Υπόδειξη:"
msgid "If you come back to it later, it may revert to its original version."
msgstr "Αν επιστρέψετε αργότερα, ενδέχεται να επανέλθει στην αρχική του μορφή."
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr "Λάθος"
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr "Μήνυμα"
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr "Σημείωση:"
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr "Ορισμός τυχαίου αριθμού:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr "Απάντηση:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr "Λύση:"
@@ -102,11 +156,41 @@ msgstr "Λύση:"
msgid "Submit your answers again to go on to the next part."
msgstr "Υποβάλετε τις απαντήσεις σας ξανά για να συνεχίσετε."
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr "Αυτή είναι μια νέα (επανατυχαιοποιημένη) έκδοση του προβλήματος."
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
"Αυτό το πρόβλημα περιέχει ένα βίντεο που πρέπει να προβληθεί στο διαδίκτυο."
@@ -115,10 +199,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr "Αυτό το πρόβλημα έχει περισσότερα από ένα μέρη."
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr "Σωστό"
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr "Χωρίς βαθμό"
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "Μπορείτε να κερδίσετε μερική πίστωση σε αυτό το πρόβλημα."
@@ -132,7 +224,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr "Μη δεκτές αλλαγές σε απαντήσεις αν συνεχίσετε στο επόμενο μέρος!"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr "Ο περιηγητής σας δεν υποστηρίζει την ετικέτα βίντεο."
@@ -140,12 +232,12 @@ msgstr "Ο περιηγητής σας δεν υποστηρίζει την ετ
msgid "Your score for this attempt is for this part only;"
msgstr "Το σκορ σας σε αυτήν την προσπάθεια είναι μόνο για αυτό το μέρος˙"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr "απάντηση"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr "στήλη"
@@ -166,15 +258,15 @@ msgstr "εάν"
msgid "otherwise"
msgstr "αλλιώς"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr "μέρος"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr "πρόβλημα"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr "σειρά"
diff --git a/lib/WeBWorK/PG/Localize/en.po b/lib/WeBWorK/PG/Localize/en.po
index b16815e40e..f5acf329f1 100644
--- a/lib/WeBWorK/PG/Localize/en.po
+++ b/lib/WeBWorK/PG/Localize/en.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:01-0500\n"
+"PO-Revision-Date: 2023-10-05 06:43-0500\n"
"Last-Translator: Jason Aubrey \n"
"Language-Team: English (United States) (http://www.transifex.com/webwork/"
"webwork2/language/en_US/)\n"
@@ -17,7 +17,43 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr ""
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr ""
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -40,12 +76,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -53,21 +89,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -75,11 +128,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -87,10 +170,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr ""
@@ -103,7 +194,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -111,12 +202,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -138,15 +229,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/es.po b/lib/WeBWorK/PG/Localize/es.po
index 14cb89f12a..c1767029ca 100644
--- a/lib/WeBWorK/PG/Localize/es.po
+++ b/lib/WeBWorK/PG/Localize/es.po
@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:01-0500\n"
+"PO-Revision-Date: 2023-10-05 06:43-0500\n"
"Last-Translator: Enrique Acosta , 2020\n"
"Language-Team: Spanish (http://app.transifex.com/webwork/webwork2/language/"
"es/)\n"
@@ -20,7 +20,44 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? "
"1 : 2;\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr ""
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr ""
+"%quant(%1,de las preguntas sigue,de las preguntas siguen) sin respuesta."
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "Correcto"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr ""
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -43,12 +80,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr "Pista:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -56,21 +93,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr "incorrecto"
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr "Nota:"
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr "Solución:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -78,11 +132,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -90,10 +174,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "Puedes obtener una fracción del puntaje total en este problema."
@@ -106,7 +198,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -114,12 +206,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -140,15 +232,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr "Problema"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/fr-CA.po b/lib/WeBWorK/PG/Localize/fr-CA.po
index 5288f308b5..81c54deb2b 100644
--- a/lib/WeBWorK/PG/Localize/fr-CA.po
+++ b/lib/WeBWorK/PG/Localize/fr-CA.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:01-0500\n"
+"PO-Revision-Date: 2023-10-05 06:43-0500\n"
"Last-Translator: Jonathan Desaulniers , 2018-2019,2021-2022\n"
"Language-Team: French (Canada) (http://app.transifex.com/webwork/webwork2/"
@@ -22,7 +22,43 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % "
"1000000 == 0 ? 1 : 2;\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% correct"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr "%quant(%1, question reste, questions restent) sans réponses."
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "Réussi"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr "Bonne réponse"
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr "Faux"
@@ -46,12 +82,12 @@ msgid "Hardcopy will always print the original version of the problem."
msgstr ""
"Le document sera toujours imprimer avec la version originale du problème."
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr "Indice :"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr "Indice:"
@@ -61,21 +97,38 @@ msgstr ""
"Si vous revenez plus tard, le problème pourrait être revenu à sa version "
"originale."
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr "Erroné"
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr "Message"
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr "Note:"
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr "Définir la source aléatoire à:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr "Solution :"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr "Solution:"
@@ -83,11 +136,41 @@ msgstr "Solution:"
msgid "Submit your answers again to go on to the next part."
msgstr "Soumettre votre réponse à nouveau pour passer à la partie suivante."
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr "Voici une nouvelle version (à nouveau randomisée) du problème."
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr "Ce problème contient une vidéo qui doit être consultée en ligne."
@@ -95,10 +178,18 @@ msgstr "Ce problème contient une vidéo qui doit être consultée en ligne."
msgid "This problem has more than one part."
msgstr "Ce problème comporte plusieurs parties."
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr "Vrai"
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr "Non classé"
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "Vous pouvez obtenir une partie des points pour ce problème."
@@ -113,7 +204,7 @@ msgid "You may not change your answers when going on to the next part!"
msgstr ""
"Vous ne pouvez pas modifier vos réponses en passant à la partie suivante!"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr "Votre navigateur ne supporte pas l'environnement vidéo."
@@ -122,12 +213,12 @@ msgid "Your score for this attempt is for this part only;"
msgstr ""
"Votre résultat pour cette tentative correspond à cette partie seulement;"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr "réponse"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr "colonne"
@@ -148,15 +239,15 @@ msgstr "Si"
msgid "otherwise"
msgstr "autrement"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr "partie"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr "problème"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr "ligne"
diff --git a/lib/WeBWorK/PG/Localize/fr.po b/lib/WeBWorK/PG/Localize/fr.po
index 28fcc99dd5..6ad9848616 100644
--- a/lib/WeBWorK/PG/Localize/fr.po
+++ b/lib/WeBWorK/PG/Localize/fr.po
@@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:01-0500\n"
+"PO-Revision-Date: 2023-10-05 06:43-0500\n"
"Last-Translator: Stéphanie Lanthier , 2011\n"
"Language-Team: French (http://app.transifex.com/webwork/webwork2/language/"
"fr/)\n"
@@ -23,7 +23,43 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % "
"1000000 == 0 ? 1 : 2;\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% correct"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr "%quant(%1, des questions restent, des questions reste) sans réponse."
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "Correct"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr ""
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -46,12 +82,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -59,21 +95,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -81,11 +134,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -93,10 +176,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr "Mise à jour réussie"
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "Vous pouvez obtenir une partie des points pour ce problème."
@@ -109,7 +200,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -117,12 +208,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -143,15 +234,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/he-IL.po b/lib/WeBWorK/PG/Localize/he-IL.po
index 8260036fd3..6353af588d 100644
--- a/lib/WeBWorK/PG/Localize/he-IL.po
+++ b/lib/WeBWorK/PG/Localize/he-IL.po
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:01-0500\n"
+"PO-Revision-Date: 2023-10-05 06:42-0500\n"
"Last-Translator: Nathan Wallach , 2022-2023\n"
"Language-Team: Hebrew (Israel) (http://app.transifex.com/webwork/webwork2/"
"language/he_IL/)\n"
@@ -22,7 +22,43 @@ msgstr ""
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % "
"1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% נכון"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr "%quant(%1, מהשאלות לא נענתה, מהשאלות לא נענו)."
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "נכון"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr "תשובה נכונה"
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr " לא נכון"
@@ -45,12 +81,12 @@ msgstr "המשך לחלק הבא"
msgid "Hardcopy will always print the original version of the problem."
msgstr "בקבצי הדפסה תמיד יודפס הגרסה המקורית של השאלה."
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr "רמז:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr "רמז: "
@@ -58,21 +94,38 @@ msgstr "רמז: "
msgid "If you come back to it later, it may revert to its original version."
msgstr "אם תחזור לשאלה בהמשל, ייתכן שהשאלה תחזור לגרסה המקורית."
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr "לא נכון"
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr "הודעות"
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr "הערה:"
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr "החלף את זרע ההגרלות אל:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr "פתרון:"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr "פתרון: "
@@ -80,11 +133,41 @@ msgstr "פתרון: "
msgid "Submit your answers again to go on to the next part."
msgstr "שלח את התשובות שוב כדי להתקדם לחלק הבא."
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr "הנה גרסה חדשה של השאלה."
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr "השאלה מכילה וידיאו שיש לראות באופן מקוון."
@@ -92,10 +175,18 @@ msgstr "השאלה מכילה וידיאו שיש לראות באופן מקוו
msgid "This problem has more than one part."
msgstr "לשאלה זו יש יותר מחלק אחד."
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr "נכון"
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr "לא נוקדו"
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "ניתן לקבל ניקוד חלקי בשאלה זו"
@@ -108,7 +199,7 @@ msgstr "אתה יכול לבקש גרסה שונה של שאלה זו לאחר
msgid "You may not change your answers when going on to the next part!"
msgstr "לא ניתן לשנות תשובות כאשר אתה מתקדם לחלק הבא!"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr "הדפדפן שלך לא תומך ב-video tag."
@@ -116,12 +207,12 @@ msgstr "הדפדפן שלך לא תומך ב-video tag."
msgid "Your score for this attempt is for this part only;"
msgstr "הציון שקבלת בהגשה זו הוא רק לחקל זה;"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr "תשובה"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr "עמודה"
@@ -142,15 +233,15 @@ msgstr "if"
msgid "otherwise"
msgstr "אחרת"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr "חלק"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr "שאלה"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr "שורה"
diff --git a/lib/WeBWorK/PG/Localize/hu.po b/lib/WeBWorK/PG/Localize/hu.po
index acee55a45d..e2eedf2d86 100644
--- a/lib/WeBWorK/PG/Localize/hu.po
+++ b/lib/WeBWorK/PG/Localize/hu.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:01-0500\n"
+"PO-Revision-Date: 2023-10-05 06:44-0500\n"
"Last-Translator: pcsiba , 2014,2016-2017\n"
"Language-Team: Hungarian (http://app.transifex.com/webwork/webwork2/language/"
"hu/)\n"
@@ -18,7 +18,43 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% helyes"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr "%quant(%1,kérdés maradt,kérdés maradt) megválaszolatlan."
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "Helyes"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr "Helyes válasz"
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -41,12 +77,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -54,21 +90,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -76,11 +129,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -88,10 +171,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr "Igaz"
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "Ezért a feladatért részpontokat kaphat. "
@@ -104,7 +195,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -112,12 +203,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr "válasz"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr "oszlop"
@@ -138,15 +229,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr "feladat"
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr "sor"
diff --git a/lib/WeBWorK/PG/Localize/ko.po b/lib/WeBWorK/PG/Localize/ko.po
index 4e691ebb7d..78ffde31c8 100644
--- a/lib/WeBWorK/PG/Localize/ko.po
+++ b/lib/WeBWorK/PG/Localize/ko.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:02-0500\n"
+"PO-Revision-Date: 2023-10-05 06:44-0500\n"
"Last-Translator: Ji-Young Ham , 2022\n"
"Language-Team: Korean (http://app.transifex.com/webwork/webwork2/language/"
"ko/)\n"
@@ -18,7 +18,43 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr ""
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "정답"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr "정답"
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -41,12 +77,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -54,21 +90,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr "오답"
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -76,11 +129,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr "다음 단계로 이동하려면 답변을 다시 제출하십시오."
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -88,10 +171,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr "채점되지 않은"
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "이 문제의 부분 점수를 받았습니다."
@@ -104,7 +195,7 @@ msgstr "이 문제의 새 버전은 마감일 이후에 받을 수 있습니다.
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -112,12 +203,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -138,15 +229,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/pg.pot b/lib/WeBWorK/PG/Localize/pg.pot
index 421a4d7df1..887760f0a4 100644
--- a/lib/WeBWorK/PG/Localize/pg.pot
+++ b/lib/WeBWorK/PG/Localize/pg.pot
@@ -14,7 +14,43 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr ""
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr ""
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -34,7 +70,7 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1516 /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1402 /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint:"
msgstr ""
@@ -42,15 +78,31 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396 /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1108 /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508 /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394 /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
msgid "Solution:"
msgstr ""
@@ -58,11 +110,35 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3179
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid "This is an essay answer text box. You can type your answer in here and, after you hit submit, it will be saved so that your instructor can grade it at a later date. If your instructor makes any comments on your answer those comments will appear on this page after the question has been graded. You can use LaTeX to make your math equations look pretty. LaTeX expressions should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3062
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -70,10 +146,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr ""
@@ -86,7 +170,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3172
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3055
msgid "Your browser does not support the video tag."
msgstr ""
@@ -94,11 +178,11 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610 /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558 /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -117,15 +201,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/ru-RU.po b/lib/WeBWorK/PG/Localize/ru-RU.po
index 3a6ced3c50..0495e38bba 100644
--- a/lib/WeBWorK/PG/Localize/ru-RU.po
+++ b/lib/WeBWorK/PG/Localize/ru-RU.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:02-0500\n"
+"PO-Revision-Date: 2023-10-05 06:44-0500\n"
"Last-Translator: FULL NAME \n"
"Language-Team: Russian (Russia) (http://app.transifex.com/webwork/webwork2/"
"language/ru_RU/)\n"
@@ -19,7 +19,43 @@ msgstr ""
"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || "
"(n%100>=11 && n%100<=14)? 2 : 3);\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr ""
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "Верно"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr "Правильные ответы"
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -42,12 +78,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -55,21 +91,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -77,11 +130,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -89,10 +172,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "Балл за эту задачу может дробиться. "
@@ -105,7 +196,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -113,12 +204,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -139,15 +230,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/tr.po b/lib/WeBWorK/PG/Localize/tr.po
index 446bdec32b..a5fa6ad025 100644
--- a/lib/WeBWorK/PG/Localize/tr.po
+++ b/lib/WeBWorK/PG/Localize/tr.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:02-0500\n"
+"PO-Revision-Date: 2023-10-05 06:44-0500\n"
"Last-Translator: FULL NAME \n"
"Language-Team: Turkish (http://app.transifex.com/webwork/webwork2/language/"
"tr/)\n"
@@ -17,7 +17,43 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% doğru"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr "Soruların %1 tanesi yanıtsız bırakıldı."
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "Doğru yanıt"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr ""
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -40,12 +76,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -53,21 +89,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -75,11 +128,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -87,10 +170,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "Bu sorudan kısmi puan alabilirsiniz."
@@ -103,7 +194,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -111,12 +202,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -137,15 +228,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/zh-CN.po b/lib/WeBWorK/PG/Localize/zh-CN.po
index 54a71c45c9..e738394966 100644
--- a/lib/WeBWorK/PG/Localize/zh-CN.po
+++ b/lib/WeBWorK/PG/Localize/zh-CN.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:02-0500\n"
+"PO-Revision-Date: 2023-10-05 06:45-0500\n"
"Last-Translator: Liping Chen , 2013\n"
"Language-Team: Chinese (China) (http://www.transifex.com/webwork/webwork2/"
"language/zh_CN/)\n"
@@ -20,7 +20,43 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% 正确"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr "%quant(%1,个问题,个问题) 未完成。"
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "正确"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr ""
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -43,12 +79,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -56,21 +92,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -78,11 +131,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -90,10 +173,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "这一题你可以得到部分成绩"
@@ -106,7 +197,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -114,12 +205,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -140,15 +231,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Localize/zh-HK.po b/lib/WeBWorK/PG/Localize/zh-HK.po
index 7a4d67a16e..a9a1d45e72 100644
--- a/lib/WeBWorK/PG/Localize/zh-HK.po
+++ b/lib/WeBWorK/PG/Localize/zh-HK.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: webwork2\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-16 14:03-0500\n"
+"PO-Revision-Date: 2023-10-05 06:45-0500\n"
"Last-Translator: Liping Chen , 2013\n"
"Language-Team: Chinese (Hong Kong) (http://app.transifex.com/webwork/"
"webwork2/language/zh_HK/)\n"
@@ -18,7 +18,43 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:285
+#. (@answerNames - $numBlank - $numCorrect - $numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1412
+msgid "%1 of the answers %plural(%1,is,are) NOT correct."
+msgstr ""
+
+#. ($numEssay)
+#: /opt/webwork/pg/macros/PG.pl:1435
+msgid "%1 of the answers will be graded later."
+msgstr ""
+
+#. (round($answerScore * 100)
+#: /opt/webwork/pg/macros/PG.pl:1157
+msgid "%1% correct"
+msgstr "%1% 正确"
+
+#. ($numBlank)
+#: /opt/webwork/pg/macros/PG.pl:1425
+msgid "%quant(%1,of the questions remains,of the questions remain) unanswered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1399
+msgid "All of the answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1390
+msgid "All of the gradeable answers are correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1149
+msgid "Correct"
+msgstr "正确"
+
+#: /opt/webwork/pg/macros/PG.pl:1308
+msgid "Correct Answer"
+msgstr ""
+
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:314
msgid "False"
msgstr ""
@@ -41,12 +77,12 @@ msgstr ""
msgid "Hardcopy will always print the original version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1518
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1519
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1404
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1405
msgid "Hint:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1517
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1403
msgid "Hint: "
msgstr ""
@@ -54,21 +90,38 @@ msgstr ""
msgid "If you come back to it later, it may revert to its original version."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1153
+msgid "Incorrect"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1319
+msgid "Message"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:396
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:422
msgid "Note:"
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1108
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:131
+msgid "Preview"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1295
+msgid "Preview of Your Answer"
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:188
msgid "Set random seed to:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1509
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1510
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1395
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1396
msgid "Solution:"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1508
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:1394
msgid "Solution: "
msgstr ""
@@ -76,11 +129,41 @@ msgstr ""
msgid "Submit your answers again to go on to the next part."
msgstr ""
+#: /opt/webwork/pg/macros/PG.pl:1378
+msgid "The answer is NOT correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1351
+msgid "The answer is correct."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1360
+msgid "The answer will be graded later."
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1369
+msgid "The question has not been answered."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:78
+msgid "This answer will be graded at a later time."
+msgstr ""
+
#: /opt/webwork/pg/macros/deprecated/problemRandomize.pl:423
msgid "This is a new (re-randomized) version of the problem."
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3181
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:145
+msgid ""
+"This is an essay answer text box. You can type your answer in here and, "
+"after you hit submit, it will be saved so that your instructor can grade it "
+"at a later date. If your instructor makes any comments on your answer those "
+"comments will appear on this page after the question has been graded. You "
+"can use LaTeX to make your math equations look pretty. LaTeX expressions "
+"should be enclosed using the parenthesis notation and not dollar signs."
+msgstr ""
+
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3064
msgid "This problem contains a video which must be viewed online."
msgstr ""
@@ -88,10 +171,18 @@ msgstr ""
msgid "This problem has more than one part."
msgstr ""
-#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:284
+#: /opt/webwork/pg/macros/parsers/parserPopUp.pl:313
msgid "True"
msgstr ""
+#: /opt/webwork/pg/macros/core/PGessaymacros.pl:60
+msgid "Ungraded"
+msgstr ""
+
+#: /opt/webwork/pg/macros/PG.pl:1290
+msgid "You Entered"
+msgstr ""
+
#: /opt/webwork/pg/macros/core/PGanswermacros.pl:1616
msgid "You can earn partial credit on this problem."
msgstr "这一题你可以得到部分成绩"
@@ -104,7 +195,7 @@ msgstr ""
msgid "You may not change your answers when going on to the next part!"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3174
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:3057
msgid "Your browser does not support the video tag."
msgstr ""
@@ -112,12 +203,12 @@ msgstr ""
msgid "Your score for this attempt is for this part only;"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:610
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:621
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:558
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:569
msgid "answer"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "column"
msgstr ""
@@ -138,15 +229,15 @@ msgstr ""
msgid "otherwise"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:627
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:575
msgid "part"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:616
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:564
msgid "problem"
msgstr ""
-#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:633
+#: /opt/webwork/pg/macros/core/PGbasicmacros.pl:581
msgid "row"
msgstr ""
diff --git a/lib/WeBWorK/PG/Translator.pm b/lib/WeBWorK/PG/Translator.pm
index e56eaf4210..931c99e59b 100644
--- a/lib/WeBWorK/PG/Translator.pm
+++ b/lib/WeBWorK/PG/Translator.pm
@@ -15,50 +15,41 @@
package WeBWorK::PG::Translator;
-use strict;
-use warnings;
-
-use utf8;
-use v5.12;
-binmode(STDOUT, ":encoding(UTF-8)");
-
-use Opcode;
-use Carp;
-
-use WWSafe;
-use PGUtil qw(pretty_print);
-use WeBWorK::PG::IO qw(fileFromPath);
-
=head1 NAME
WeBWorK::PG::Translator - Evaluate PG code and evaluate answers safely
=head1 SYNPOSIS
- my $pt = new WeBWorK::PG::Translator; # create a translator
+ my $pt = WeBWorK::PG::Translator->new; # create a translator
$pt->environment(\%envir); # provide the environment variable for the problem
- $pt->initialize(); # initialize the translator
- $pt-> set_mask(); # set the operation mask for the translator safe compartment
+ $pt->initialize; # initialize the translator
+ $pt->set_mask; # set the operation mask for the translator safe compartment
+
$pt->source_string($source); # provide the source string for the problem
+ # or
+ $pt->source_file($sourceFilePath); # provide the proble file containing the source
# Load the unprotected macro files.
# These files are evaluated with the Safe compartment wide open.
# Other macros are loaded from within the problem using loadMacros.
- $pt->unrestricted_load("${courseScriptsDirectory}PG.pl");
+ # This should not be done if the safe cache is used which is only the case if $ENV{MOJO_MODE} exists.
+ $pt->unrestricted_load("${pgMacrosDirectory}PG.pl");
- $pt->translate(); # translate the problem (the following pieces of information are created)
+ $pt->translate; # translate the problem (the following pieces of information are created)
- $PG_PROBLEM_TEXT_ARRAY_REF = $pt->ra_text(); # output text for the body of the HTML file (in array form)
- $PG_PROBLEM_TEXT_REF = $pt->r_text(); # output text for the body of the HTML file
- $PG_HEADER_TEXT_REF = $pt->r_header; # text for the header of the HTML file
- $PG_POST_HEADER_TEXT_REF = $pt->r_post_header
+ $PG_PROBLEM_TEXT_REF = $pt->r_text; # reference to output text for the body of problem
+ $PG_HEADER_TEXT_REF = $pt->r_header; # reference to text for the header in HTML output
+ $PG_POST_HEADER_TEXT_REF = $pt->r_post_header;
$PG_ANSWER_HASH_REF = $pt->rh_correct_answers; # a hash of answer evaluators
$PG_FLAGS_REF = $pt->rh_flags; # misc. status flags.
- $pt->process_answers; # evaluates all of the answers
+ $pt->process_answers; # evaluates all of the answers
+ my $rh_answer_results = $pt->rh_evaluated_answers; # provides a hash of the results of evaluating the answers.
+ my $rh_problem_result = $pt->grade_problem(%options); # grades the problem.
- my $rh_answer_results = $pt->rh_evaluated_answers; # provides a hash of the results of evaluating the answers.
- my $rh_problem_result = $pt->grade_problem; # grades the problem using the default problem grading method.
+ $pt->post_process_content; # Execute macro or problem hooks that further modify the problem content.
+ $pt->stringify_answers; # Convert objects to strings in the answer hash
=head1 DESCRIPTION
@@ -66,6 +57,21 @@ This module defines an object which will translate a problem written in the Prob
=cut
+use strict;
+use warnings;
+
+use utf8;
+use v5.12;
+binmode(STDOUT, ":encoding(UTF-8)");
+
+use Opcode;
+use Carp;
+use Mojo::DOM;
+
+use WWSafe;
+use PGUtil qw(pretty_print);
+use WeBWorK::PG::IO qw(fileFromPath);
+
=head2 be_strict
This creates a substitute for C