Plugins run inside a sandboxed iframe from an opaque origin — the browser treats the plugin as if it has no origin at all. This means that <script> tags pointing to external CDN URLs will fail with a CORS error:
<!-- ❌ This will fail — CORS blocks cross-origin scripts from an opaque origin -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
The browser blocks the request because the opaque origin cannot satisfy the CDN's CORS policy.
The solution is straightforward: download the library's minified build and place it alongside your index.html in the plugin directory.
Download the minified .js (and .css if needed) file from the library's releases page, npm, or CDN. For example, for Chart.js:
chart.umd.min.js from the releases page or copy it from node_modules/chart.js/dist/plugins/
my-chart/
index.html
script.js
chart.umd.min.js ← Bundled library
monkeyCodeInput.js ← Auto-injected, no need to include
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="./monkeyCodeInput.js"></script>
<script src="./chart.umd.min.js"></script> <!-- ✅ Relative path -->
<script src="./script.js"></script>
</head>
<body>
<canvas id="myChart" width="380" height="360"></canvas>
</body>
</html>
This example reads a list of numbers from the sample input and renders them as a bar chart using Chart.js.
Plugin directory structure:
plugins/
bar-chart/
index.html
chart.umd.min.js ← Downloaded from Chart.js releases
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./monkeyCodeInput.js"></script>
<script src="./chart.umd.min.js"></script>
<style>
body { margin: 0; display: flex; align-items: center; justify-content: center; height: 100vh; }
</style>
</head>
<body>
<canvas id="chart" width="380" height="360"></canvas>
<script>
// Read input: first line is n, second line is n space-separated integers
const lines = inputLines()
const n = parseInt(lines[0])
const values = lines[1].split(' ').map(Number)
const labels = values.map((_, i) => `Item ${i + 1}`)
new Chart(document.getElementById('chart'), {
type: 'bar',
data: {
labels,
datasets: [{
label: 'Values',
data: values,
backgroundColor: '#6366f1',
borderRadius: 4,
}]
},
options: {
responsive: false,
plugins: { legend: { display: false } },
scales: { y: { beginAtZero: true } }
}
})
</script>
</body>
</html>
Problem statement reference:
\plugin{bar-chart}
Sample input format:
5
3 1 4 1 5
The entire problem package must be under 50 MB. When bundling libraries:
.min.js) build, not the development buildThe same rule applies to CSS frameworks. Download the stylesheet and reference it locally:
plugins/
styled-viz/
index.html
normalize.min.css ← Downloaded locally
script.js
<link rel="stylesheet" href="./normalize.min.css">