diff --git a/src/Documentation/doc/index.md b/src/Documentation/doc/index.md
index fcb4f0c4d..941e957a0 100644
--- a/src/Documentation/doc/index.md
+++ b/src/Documentation/doc/index.md
@@ -43,6 +43,7 @@
## Resources
+- [NS API documentation](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.ns.md)
- [Learn to program](programming/learn.md)
- [Remote API](programming/remote_api.md)
- [Game Frozen or Stuck?](programming/game_frozen.md)
diff --git a/src/ScriptEditor/ui/Toolbar.tsx b/src/ScriptEditor/ui/Toolbar.tsx
index 45ceef1ca..366781922 100644
--- a/src/ScriptEditor/ui/Toolbar.tsx
+++ b/src/ScriptEditor/ui/Toolbar.tsx
@@ -15,7 +15,6 @@ import SettingsIcon from "@mui/icons-material/Settings";
import { makeTheme, sanitizeTheme } from "./themes";
-import { CONSTANTS } from "../../Constants";
import { Modal } from "../../ui/React/Modal";
import { Page } from "../../ui/Router";
import { Router } from "../../ui/GameRoot";
@@ -23,11 +22,8 @@ import { useBoolean } from "../../ui/React/hooks";
import { Settings } from "../../Settings/Settings";
import { OptionsModal, OptionsModalProps } from "./OptionsModal";
import { useScriptEditorContext } from "./ScriptEditorContext";
+import { getNsApiDocumentationUrl } from "../../utils/StringHelperFunctions";
-const docUrl =
- "https://github.com/bitburner-official/bitburner-src/blob/" +
- (CONSTANTS.isDevBranch ? "dev" : "stable") +
- "/markdown/bitburner.ns.md";
type IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
interface IProps {
@@ -75,7 +71,7 @@ export function Toolbar({ editor, onSave }: IProps) {
Terminal (Ctrl/Cmd + b)
-
+
Documentation
diff --git a/src/ui/MD/a.tsx b/src/ui/MD/a.tsx
index 317795c43..80720ba83 100644
--- a/src/ui/MD/a.tsx
+++ b/src/ui/MD/a.tsx
@@ -3,6 +3,7 @@ import { Link } from "@mui/material";
import { useNavigator } from "../React/Documentation";
import { CorruptableText } from "../React/CorruptableText";
import { Player } from "@player";
+import { getNsApiDocumentationUrl } from "../../utils/StringHelperFunctions";
export const isSpoiler = (title: string): boolean => title.includes("advanced/") && Player.sourceFileLvl(1) === 0;
@@ -13,12 +14,19 @@ export const A = (props: React.PropsWithChildren<{ href?: string }>): React.Reac
const onClick = (event: React.MouseEvent) => {
navigator.navigate(ref, event.ctrlKey);
};
- if (ref.startsWith("http"))
+ if (ref.startsWith("http")) {
+ let href = ref;
+ // The URL of NS API documentation in index.md always points to the stable branch, so we need to intercept it here
+ // and change it if necessary.
+ if (href === getNsApiDocumentationUrl(false)) {
+ href = getNsApiDocumentationUrl();
+ }
return (
-
+
{props.children}
);
+ }
if (isSpoiler(ref))
return (
diff --git a/src/utils/StringHelperFunctions.ts b/src/utils/StringHelperFunctions.ts
index 004f8d80c..792f27395 100644
--- a/src/utils/StringHelperFunctions.ts
+++ b/src/utils/StringHelperFunctions.ts
@@ -1,11 +1,12 @@
import { Settings } from "../Settings/Settings";
+import { CONSTANTS } from "../Constants";
/*
Converts a date representing time in milliseconds to a string with the format H hours M minutes and S seconds
e.g. 10000 -> "10 seconds"
120000 -> "2 minutes and 0 seconds"
*/
-function convertTimeMsToTimeElapsedString(time: number, showMilli = false): string {
+export function convertTimeMsToTimeElapsedString(time: number, showMilli = false): string {
const negFlag = time < 0;
time = Math.abs(Math.floor(time));
const millisecondsPerSecond = 1000;
@@ -51,7 +52,7 @@ function convertTimeMsToTimeElapsedString(time: number, showMilli = false): stri
}
// Finds the longest common starting substring in a set of strings
-function longestCommonStart(strings: string[]): string {
+export function longestCommonStart(strings: string[]): string {
if (!containsAllStrings(strings)) {
return "";
}
@@ -72,12 +73,12 @@ function longestCommonStart(strings: string[]): string {
}
// Returns whether an array contains entirely of string objects
-function containsAllStrings(arr: string[]): boolean {
+export function containsAllStrings(arr: string[]): boolean {
return arr.every((value) => typeof value === "string");
}
// Generates a random alphanumeric string with N characters
-function generateRandomString(n: number): string {
+export function generateRandomString(n: number): string {
let str = "";
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
@@ -95,7 +96,7 @@ function generateRandomString(n: number): string {
* @param seed A seed to randomize the result
* @returns An hexadecimal string representation of the hashed input
*/
-function cyrb53(str: string, seed = 0): string {
+export function cyrb53(str: string, seed = 0): string {
let h1 = 0xdeadbeef ^ seed;
let h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
@@ -108,23 +109,19 @@ function cyrb53(str: string, seed = 0): string {
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16);
}
-function capitalizeFirstLetter(s: string): string {
+export function capitalizeFirstLetter(s: string): string {
return s.charAt(0).toUpperCase() + s.slice(1);
}
-function capitalizeEachWord(s: string): string {
+export function capitalizeEachWord(s: string): string {
return s
.split(" ")
.map((word) => capitalizeFirstLetter(word))
.join(" ");
}
-export {
- convertTimeMsToTimeElapsedString,
- longestCommonStart,
- containsAllStrings,
- generateRandomString,
- cyrb53,
- capitalizeFirstLetter,
- capitalizeEachWord,
-};
+export function getNsApiDocumentationUrl(isDevBranch = CONSTANTS.isDevBranch): string {
+ return `https://github.com/bitburner-official/bitburner-src/blob/${
+ isDevBranch ? "dev" : "stable"
+ }/markdown/bitburner.ns.md`;
+}