mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	blueslip: Make stack trace more readable.
The stack trace popup is now sourcemapped and each stackframe have a expandable code context window. [anders@zulipchat.com: Rebased and simplified.]
This commit is contained in:
		@@ -427,6 +427,7 @@
 | 
				
			|||||||
                "no-magic-numbers": "off",
 | 
					                "no-magic-numbers": "off",
 | 
				
			||||||
                "semi": "off",
 | 
					                "semi": "off",
 | 
				
			||||||
                "no-unused-vars": "off",
 | 
					                "no-unused-vars": "off",
 | 
				
			||||||
 | 
					                "no-useless-constructor": "off",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                "@typescript-eslint/adjacent-overload-signatures": "error",
 | 
					                "@typescript-eslint/adjacent-overload-signatures": "error",
 | 
				
			||||||
                "@typescript-eslint/array-type": "error",
 | 
					                "@typescript-eslint/array-type": "error",
 | 
				
			||||||
@@ -451,7 +452,7 @@
 | 
				
			|||||||
                "@typescript-eslint/no-extraneous-class": "error",
 | 
					                "@typescript-eslint/no-extraneous-class": "error",
 | 
				
			||||||
                "@typescript-eslint/no-for-in-array": "off",
 | 
					                "@typescript-eslint/no-for-in-array": "off",
 | 
				
			||||||
                "@typescript-eslint/no-inferrable-types": "error",
 | 
					                "@typescript-eslint/no-inferrable-types": "error",
 | 
				
			||||||
                "@typescript-eslint/no-magic-numbers": "error",
 | 
					                "@typescript-eslint/no-magic-numbers": "off",
 | 
				
			||||||
                "@typescript-eslint/no-misused-new": "error",
 | 
					                "@typescript-eslint/no-misused-new": "error",
 | 
				
			||||||
                "@typescript-eslint/no-namespace": "error",
 | 
					                "@typescript-eslint/no-namespace": "error",
 | 
				
			||||||
                "@typescript-eslint/no-non-null-assertion": "off",
 | 
					                "@typescript-eslint/no-non-null-assertion": "off",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										56
									
								
								frontend_tests/node_tests/blueslip_stacktrace.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								frontend_tests/node_tests/blueslip_stacktrace.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					const blueslip_stacktrace = zrequire("blueslip_stacktrace");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run_test("clean_path", () => {
 | 
				
			||||||
 | 
					    // Local file
 | 
				
			||||||
 | 
					    assert.strictEqual(
 | 
				
			||||||
 | 
					        blueslip_stacktrace.clean_path("webpack:///static/js/upload.js"),
 | 
				
			||||||
 | 
					        "/static/js/upload.js"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Third party library (jQuery)
 | 
				
			||||||
 | 
					    assert.strictEqual(
 | 
				
			||||||
 | 
					        blueslip_stacktrace.clean_path(
 | 
				
			||||||
 | 
					            "webpack:///.-npm-cache/de76fb6f582a29b053274f9048b6158091351048/node_modules/jquery/dist/jquery.js"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        "jquery/dist/jquery.js"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Third party library (underscore)
 | 
				
			||||||
 | 
					    assert.strictEqual(
 | 
				
			||||||
 | 
					        blueslip_stacktrace.clean_path(
 | 
				
			||||||
 | 
					            "webpack:///.-npm-cache/de76fb6f582a29b053274f9048b…58091351048/node_modules/underscore/underscore.js"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        "underscore/underscore.js"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run_test("clean_function_name", () => {
 | 
				
			||||||
 | 
					    assert.deepEqual(blueslip_stacktrace.clean_function_name(undefined), undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Local file
 | 
				
			||||||
 | 
					    assert.deepEqual(
 | 
				
			||||||
 | 
					        blueslip_stacktrace.clean_function_name("Object../static/js/upload.js.exports.options"),
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            scope: "Object../static/js/upload.js.exports.",
 | 
				
			||||||
 | 
					            name: "options",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Third party library (jQuery)
 | 
				
			||||||
 | 
					    assert.deepEqual(blueslip_stacktrace.clean_function_name("mightThrow"), {
 | 
				
			||||||
 | 
					        scope: "",
 | 
				
			||||||
 | 
					        name: "mightThrow",
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Third party library (underscore)
 | 
				
			||||||
 | 
					    assert.deepEqual(
 | 
				
			||||||
 | 
					        blueslip_stacktrace.clean_function_name(
 | 
				
			||||||
 | 
					            "Function.../zulip-npm-cache/de76fb6f582a29b053274f…es/underscore/underscore.js?3817._.each._.forEach"
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            scope:
 | 
				
			||||||
 | 
					                "Function.../zulip-npm-cache/de76fb6f582a29b053274f…es/underscore/underscore.js?3817._.each._.",
 | 
				
			||||||
 | 
					            name: "forEach",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -48,6 +48,7 @@
 | 
				
			|||||||
    "postcss-nested": "^4.1.2",
 | 
					    "postcss-nested": "^4.1.2",
 | 
				
			||||||
    "postcss-scss": "^2.0.0",
 | 
					    "postcss-scss": "^2.0.0",
 | 
				
			||||||
    "postcss-simple-vars": "^5.0.2",
 | 
					    "postcss-simple-vars": "^5.0.2",
 | 
				
			||||||
 | 
					    "regenerator-runtime": "^0.13.3",
 | 
				
			||||||
    "script-loader": "^0.7.2",
 | 
					    "script-loader": "^0.7.2",
 | 
				
			||||||
    "shebang-loader": "^0.0.1",
 | 
					    "shebang-loader": "^0.0.1",
 | 
				
			||||||
    "simplebar": "^4.1.0",
 | 
					    "simplebar": "^4.1.0",
 | 
				
			||||||
@@ -55,6 +56,7 @@
 | 
				
			|||||||
    "sorttable": "^1.0.2",
 | 
					    "sorttable": "^1.0.2",
 | 
				
			||||||
    "source-sans-pro": "^3.6.0",
 | 
					    "source-sans-pro": "^3.6.0",
 | 
				
			||||||
    "spectrum-colorpicker": "^1.8.0",
 | 
					    "spectrum-colorpicker": "^1.8.0",
 | 
				
			||||||
 | 
					    "stacktrace-gps": "^3.0.3",
 | 
				
			||||||
    "style-loader": "^1.0.0",
 | 
					    "style-loader": "^1.0.0",
 | 
				
			||||||
    "terser-webpack-plugin": "^2.1.0",
 | 
					    "terser-webpack-plugin": "^2.1.0",
 | 
				
			||||||
    "to-markdown": "^3.1.0",
 | 
					    "to-markdown": "^3.1.0",
 | 
				
			||||||
@@ -69,6 +71,7 @@
 | 
				
			|||||||
    "zxcvbn": "^4.4.2"
 | 
					    "zxcvbn": "^4.4.2"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
 | 
					    "@types/jquery": "^3.3.31",
 | 
				
			||||||
    "@types/node": "^12.0.7",
 | 
					    "@types/node": "^12.0.7",
 | 
				
			||||||
    "@types/underscore": "^1.8.18",
 | 
					    "@types/underscore": "^1.8.18",
 | 
				
			||||||
    "@types/webpack": "^4.4.32",
 | 
					    "@types/webpack": "^4.4.32",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,8 @@
 | 
				
			|||||||
// in order to be able to report exceptions that occur during their
 | 
					// in order to be able to report exceptions that occur during their
 | 
				
			||||||
// execution.
 | 
					// execution.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var blueslip_stacktrace = require("./blueslip_stacktrace");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (Error.stackTraceLimit !== undefined) {
 | 
					if (Error.stackTraceLimit !== undefined) {
 | 
				
			||||||
    Error.stackTraceLimit = 100000;
 | 
					    Error.stackTraceLimit = 100000;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -78,20 +80,6 @@ exports.get_log = function blueslip_get_log() {
 | 
				
			|||||||
    return logger.get_log();
 | 
					    return logger.get_log();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Format error stacks using the ErrorStackParser
 | 
					 | 
				
			||||||
// external library
 | 
					 | 
				
			||||||
function getErrorStack(stack) {
 | 
					 | 
				
			||||||
    var ex = new Error();
 | 
					 | 
				
			||||||
    ex.stack = stack;
 | 
					 | 
				
			||||||
    return ErrorStackParser
 | 
					 | 
				
			||||||
        .parse(ex)
 | 
					 | 
				
			||||||
        .map(function (stackFrame) {
 | 
					 | 
				
			||||||
            return stackFrame.lineNumber
 | 
					 | 
				
			||||||
            + ': ' + stackFrame.fileName
 | 
					 | 
				
			||||||
            + ' | ' + stackFrame.functionName;
 | 
					 | 
				
			||||||
        }).join('\n');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var reported_errors = {};
 | 
					var reported_errors = {};
 | 
				
			||||||
var last_report_attempt = {};
 | 
					var last_report_attempt = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -105,8 +93,7 @@ function report_error(msg, stack, opts) {
 | 
				
			|||||||
    if (page_params.debug_mode) {
 | 
					    if (page_params.debug_mode) {
 | 
				
			||||||
        // In development, we display blueslip errors in the web UI,
 | 
					        // In development, we display blueslip errors in the web UI,
 | 
				
			||||||
        // to make them hard to miss.
 | 
					        // to make them hard to miss.
 | 
				
			||||||
        stack = getErrorStack(stack);
 | 
					        blueslip_stacktrace.display_stacktrace(msg, stack);
 | 
				
			||||||
        exports.display_errors_on_screen(msg, stack);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var key = ':' + msg + stack;
 | 
					    var key = ':' + msg + stack;
 | 
				
			||||||
@@ -253,15 +240,6 @@ exports.warn = function blueslip_warn (msg, more_info) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exports.display_errors_on_screen = function (error, stack) {
 | 
					 | 
				
			||||||
    var $exit = "<div class='exit'></div>";
 | 
					 | 
				
			||||||
    var $error = "<div class='error'>" + error + "</div>";
 | 
					 | 
				
			||||||
    var $pre = "<pre>" + stack + "</pre>";
 | 
					 | 
				
			||||||
    var $alert = $("<div class='alert browser-alert home-error-bar'></div>").html($error + $exit + $pre);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $(".app .alert-box").append($alert.addClass("show"));
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
exports.error = function blueslip_error (msg, more_info, stack) {
 | 
					exports.error = function blueslip_error (msg, more_info, stack) {
 | 
				
			||||||
    if (stack === undefined) {
 | 
					    if (stack === undefined) {
 | 
				
			||||||
        stack = Error().stack;
 | 
					        stack = Error().stack;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										97
									
								
								static/js/blueslip_stacktrace.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								static/js/blueslip_stacktrace.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					import $ from "jquery";
 | 
				
			||||||
 | 
					import ErrorStackParser from "error-stack-parser";
 | 
				
			||||||
 | 
					import StackTraceGPS from "stacktrace-gps";
 | 
				
			||||||
 | 
					import render_blueslip_stacktrace from "../templates/blueslip_stacktrace.hbs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FunctionName = {
 | 
				
			||||||
 | 
					    scope: string;
 | 
				
			||||||
 | 
					    name: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NumberedLine = {
 | 
				
			||||||
 | 
					    line_number: number;
 | 
				
			||||||
 | 
					    line: string;
 | 
				
			||||||
 | 
					    focus: boolean;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CleanStackFrame = {
 | 
				
			||||||
 | 
					    full_path: string;
 | 
				
			||||||
 | 
					    show_path: string;
 | 
				
			||||||
 | 
					    function_name: FunctionName;
 | 
				
			||||||
 | 
					    line_number: number;
 | 
				
			||||||
 | 
					    context: NumberedLine[] | undefined;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function clean_path(full_path: string): string {
 | 
				
			||||||
 | 
					    // If the file is local, just show the filename.
 | 
				
			||||||
 | 
					    // Otherwise, show the full path starting from node_modules.
 | 
				
			||||||
 | 
					    const idx = full_path.indexOf("/node_modules/");
 | 
				
			||||||
 | 
					    if (idx !== -1) {
 | 
				
			||||||
 | 
					        return full_path.slice(idx + "/node_modules/".length);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (full_path.startsWith("webpack://")) {
 | 
				
			||||||
 | 
					        return full_path.slice("webpack://".length);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return full_path;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function clean_function_name(
 | 
				
			||||||
 | 
					    function_name: string | undefined
 | 
				
			||||||
 | 
					): { scope: string; name: string } | undefined {
 | 
				
			||||||
 | 
					    if (function_name === undefined) {
 | 
				
			||||||
 | 
					        return undefined;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const idx = function_name.lastIndexOf(".");
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        scope: function_name.slice(0, idx + 1),
 | 
				
			||||||
 | 
					        name: function_name.slice(idx + 1),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const sourceCache: { [source: string]: string } = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const stack_trace_gps = new StackTraceGPS({ sourceCache });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function get_context(location: StackFrame.StackFrame): NumberedLine[] | undefined {
 | 
				
			||||||
 | 
					    const sourceContent = sourceCache[location.getFileName()];
 | 
				
			||||||
 | 
					    if (sourceContent === undefined) {
 | 
				
			||||||
 | 
					        return undefined;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const lines = sourceContent.split("\n");
 | 
				
			||||||
 | 
					    const line_number = location.getLineNumber();
 | 
				
			||||||
 | 
					    const lo_line_num = Math.max(line_number - 5, 0);
 | 
				
			||||||
 | 
					    const hi_line_num = Math.min(line_number + 4, lines.length);
 | 
				
			||||||
 | 
					    return lines.slice(lo_line_num, hi_line_num).map((line: string, i: number) => ({
 | 
				
			||||||
 | 
					        line_number: lo_line_num + i + 1,
 | 
				
			||||||
 | 
					        line,
 | 
				
			||||||
 | 
					        focus: lo_line_num + i + 1 === line_number,
 | 
				
			||||||
 | 
					    }));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function display_stacktrace(error: string, stack: string): Promise<void> {
 | 
				
			||||||
 | 
					    const ex = new Error();
 | 
				
			||||||
 | 
					    ex.stack = stack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const stackframes: CleanStackFrame[] = await Promise.all(
 | 
				
			||||||
 | 
					        ErrorStackParser.parse(ex).map(async (stack_frame: ErrorStackParser.StackFrame) => {
 | 
				
			||||||
 | 
					            const location = await stack_trace_gps.getMappedLocation(
 | 
				
			||||||
 | 
					                // Work around mistake in ErrorStackParser.StackFrame definition
 | 
				
			||||||
 | 
					                // https://github.com/stacktracejs/error-stack-parser/pull/49
 | 
				
			||||||
 | 
					                (stack_frame as unknown) as StackFrame.StackFrame
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            return {
 | 
				
			||||||
 | 
					                full_path: location.getFileName(),
 | 
				
			||||||
 | 
					                show_path: clean_path(location.getFileName()),
 | 
				
			||||||
 | 
					                line_number: location.getLineNumber(),
 | 
				
			||||||
 | 
					                function_name: clean_function_name(location.getFunctionName()),
 | 
				
			||||||
 | 
					                context: get_context(location),
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const $alert = $("<div class='stacktrace'>").html(
 | 
				
			||||||
 | 
					        render_blueslip_stacktrace({ error, stackframes })
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    $(".alert-box").append($alert);
 | 
				
			||||||
 | 
					    $alert.addClass("show");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -18,7 +18,6 @@ import "handlebars/dist/cjs/handlebars.runtime.js";
 | 
				
			|||||||
import "to-markdown/dist/to-markdown.js";
 | 
					import "to-markdown/dist/to-markdown.js";
 | 
				
			||||||
import "flatpickr/dist/flatpickr.js";
 | 
					import "flatpickr/dist/flatpickr.js";
 | 
				
			||||||
import "flatpickr/dist/plugins/confirmDate/confirmDate.js";
 | 
					import "flatpickr/dist/plugins/confirmDate/confirmDate.js";
 | 
				
			||||||
import "error-stack-parser/dist/error-stack-parser.min.js";
 | 
					 | 
				
			||||||
import "sortablejs/Sortable.js";
 | 
					import "sortablejs/Sortable.js";
 | 
				
			||||||
import "../../generated/emoji/emoji_codes.js";
 | 
					import "../../generated/emoji/emoji_codes.js";
 | 
				
			||||||
import "../../generated/pygments_data.js";
 | 
					import "../../generated/pygments_data.js";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -521,8 +521,8 @@ exports.initialize = function () {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // this will hide the alerts that you click "x" on.
 | 
					    // this will hide the alerts that you click "x" on.
 | 
				
			||||||
    $("body").on("click", ".alert .exit", function () {
 | 
					    $("body").on("click", ".alert-box > div .exit", function () {
 | 
				
			||||||
        var $alert = $(this).closest(".alert");
 | 
					        var $alert = $(this).closest(".alert-box > div");
 | 
				
			||||||
        $alert.addClass("fade-out");
 | 
					        $alert.addClass("fade-out");
 | 
				
			||||||
        setTimeout(function () {
 | 
					        setTimeout(function () {
 | 
				
			||||||
            $alert.removeClass("fade-out show");
 | 
					            $alert.removeClass("fade-out show");
 | 
				
			||||||
@@ -533,6 +533,10 @@ exports.initialize = function () {
 | 
				
			|||||||
        settings_toggle.toggle_org_setting_collapse();
 | 
					        settings_toggle.toggle_org_setting_collapse();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $(".alert-box").on("click", ".stackframe .expand", function () {
 | 
				
			||||||
 | 
					        $(this).parent().siblings(".code-context").toggle("fast");
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // COMPOSE
 | 
					    // COMPOSE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // NB: This just binds to current elements, and won't bind to elements
 | 
					    // NB: This just binds to current elements, and won't bind to elements
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								static/js/hbs.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								static/js/hbs.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					declare module "*.hbs" {
 | 
				
			||||||
 | 
					    const render: (context: unknown) => string;
 | 
				
			||||||
 | 
					    export = render;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,11 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "compilerOptions": {
 | 
					    "compilerOptions": {
 | 
				
			||||||
 | 
					        "baseUrl": ".",
 | 
				
			||||||
 | 
					        "paths": {
 | 
				
			||||||
 | 
					            "*": ["types/*"],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "typeRoots": ["types"],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Typescript 3.4 added the --incremental flag but its API is not
 | 
					        /* Typescript 3.4 added the --incremental flag but its API is not
 | 
				
			||||||
         * currently public so ts-loader cannot use it yet.
 | 
					         * currently public so ts-loader cannot use it yet.
 | 
				
			||||||
         * Tracking issue: https://github.com/microsoft/TypeScript/issues/29978
 | 
					         * Tracking issue: https://github.com/microsoft/TypeScript/issues/29978
 | 
				
			||||||
@@ -8,8 +14,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        /* Basic options */
 | 
					        /* Basic options */
 | 
				
			||||||
        "noEmit": true,
 | 
					        "noEmit": true,
 | 
				
			||||||
        "target": "es5",
 | 
					        "target": "ES2019",
 | 
				
			||||||
        "module": "es6",
 | 
					        "module": "ES6",
 | 
				
			||||||
        "esModuleInterop": true,
 | 
					        "esModuleInterop": true,
 | 
				
			||||||
        "moduleResolution": "node",
 | 
					        "moduleResolution": "node",
 | 
				
			||||||
        "sourceMap": true,
 | 
					        "sourceMap": true,
 | 
				
			||||||
@@ -25,5 +31,8 @@
 | 
				
			|||||||
        "noUnusedParameters": true,
 | 
					        "noUnusedParameters": true,
 | 
				
			||||||
        "noImplicitReturns": true,
 | 
					        "noImplicitReturns": true,
 | 
				
			||||||
        "noFallthroughCasesInSwitch": true,
 | 
					        "noFallthroughCasesInSwitch": true,
 | 
				
			||||||
    }
 | 
					    },
 | 
				
			||||||
 | 
					    "exclude": [
 | 
				
			||||||
 | 
					        "types",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								static/js/types/stacktrace-gps/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								static/js/types/stacktrace-gps/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					// https://github.com/stacktracejs/stackframe/pull/27
 | 
				
			||||||
 | 
					/// <reference types="stackframe/stackframe" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import SourceMap from "source-map";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare namespace StackTraceGPS {
 | 
				
			||||||
 | 
					    type StackTraceGPSOptions = {
 | 
				
			||||||
 | 
					        sourceCache?: { [url: string]: string };
 | 
				
			||||||
 | 
					        sourceMapConsumerCache?: { [sourceMappingUrl: string]: SourceMap.SourceMapConsumer };
 | 
				
			||||||
 | 
					        offline?: boolean;
 | 
				
			||||||
 | 
					        ajax?(url: string): Promise<string>;
 | 
				
			||||||
 | 
					        atob?(base64: string): string;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// eslint-disable-next-line no-redeclare
 | 
				
			||||||
 | 
					declare class StackTraceGPS {
 | 
				
			||||||
 | 
					    constructor(options?: StackTraceGPS.StackTraceGPSOptions);
 | 
				
			||||||
 | 
					    pinpoint(stackframe: StackFrame.StackFrame): Promise<StackFrame.StackFrame>;
 | 
				
			||||||
 | 
					    findFunctionName(stackframe: StackFrame.StackFrame): Promise<StackFrame.StackFrame>;
 | 
				
			||||||
 | 
					    getMappedLocation(stackframe: StackFrame.StackFrame): Promise<StackFrame.StackFrame>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export = StackTraceGPS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export as namespace StackTraceGPS; // global for non-module UMD users
 | 
				
			||||||
@@ -48,6 +48,104 @@ $alert-error-red: hsl(0, 80%, 40%);
 | 
				
			|||||||
    width: 900px;
 | 
					    width: 900px;
 | 
				
			||||||
    margin-left: calc(50% - 450px);
 | 
					    margin-left: calc(50% - 450px);
 | 
				
			||||||
    z-index: 220;
 | 
					    z-index: 220;
 | 
				
			||||||
 | 
					    max-height: 100%;
 | 
				
			||||||
 | 
					    overflow-y: auto;
 | 
				
			||||||
 | 
					    overscroll-behavior: contain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .stacktrace {
 | 
				
			||||||
 | 
					        @extend .alert-display;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .stacktrace {
 | 
				
			||||||
 | 
					        @extend .alert-animations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        font-size: 1rem;
 | 
				
			||||||
 | 
					        color: hsl(0, 80%, 40%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        margin-top: 5px;
 | 
				
			||||||
 | 
					        padding: 1rem 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        background-color: hsl(0, 100%, 98%);
 | 
				
			||||||
 | 
					        border-radius: 4px;
 | 
				
			||||||
 | 
					        border: 1px solid hsl(0, 80%, 40%);
 | 
				
			||||||
 | 
					        box-shadow: 0 0 2px hsl(0, 80%, 40%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .stacktrace-header {
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
 | 
					            justify-content: space-between;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .message {
 | 
				
			||||||
 | 
					                flex: 1 1 auto;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .warning-symbol,
 | 
				
			||||||
 | 
					            .exit {
 | 
				
			||||||
 | 
					                flex: 0 0 auto;
 | 
				
			||||||
 | 
					                font-size: 1.3rem;
 | 
				
			||||||
 | 
					                padding: 0 1rem;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .exit::after {
 | 
				
			||||||
 | 
					                cursor: pointer;
 | 
				
			||||||
 | 
					                font-size: 2.3rem;
 | 
				
			||||||
 | 
					                content: "\d7";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .stacktrace-content {
 | 
				
			||||||
 | 
					            font-family: monospace;
 | 
				
			||||||
 | 
					            font-size: 0.85rem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            margin-top: 1rem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .stackframe {
 | 
				
			||||||
 | 
					                padding-left: calc(3.3rem - 14px);
 | 
				
			||||||
 | 
					                padding-right: 1rem;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .expand {
 | 
				
			||||||
 | 
					            cursor: pointer;
 | 
				
			||||||
 | 
					            color: hsl(0, 32%, 83%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            &:hover {
 | 
				
			||||||
 | 
					                color: hsl(0, 0%, 20%);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .subtle {
 | 
				
			||||||
 | 
					            color: hsl(0, 7%, 45%);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .code-context {
 | 
				
			||||||
 | 
					            color: hsl(0, 7%, 15%);
 | 
				
			||||||
 | 
					            background-color: hsl(0, 7%, 98%);
 | 
				
			||||||
 | 
					            background-color: hsl(0, 7%, 98%);
 | 
				
			||||||
 | 
					            box-shadow:
 | 
				
			||||||
 | 
					                inset 0px 11px 10px -10px hsl(0, 7%, 70%),
 | 
				
			||||||
 | 
					                inset 0px -11px 10px -10px hsl(0, 7%, 70%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            margin-top: 1em;
 | 
				
			||||||
 | 
					            margin-bottom: 1em;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .code-context-content {
 | 
				
			||||||
 | 
					                padding: 1rem 0;
 | 
				
			||||||
 | 
					                white-space: pre;
 | 
				
			||||||
 | 
					                overflow-x: auto;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .line-number {
 | 
				
			||||||
 | 
					                width: 3rem;
 | 
				
			||||||
 | 
					                display: inline-block;
 | 
				
			||||||
 | 
					                text-align: right;
 | 
				
			||||||
 | 
					                color: hsl(0, 7%, 35%);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .focus-line {
 | 
				
			||||||
 | 
					                background-color: hsl(0, 7%, 90%);
 | 
				
			||||||
 | 
					                width: 100%;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .alert {
 | 
					    .alert {
 | 
				
			||||||
        @extend .alert-animations;
 | 
					        @extend .alert-animations;
 | 
				
			||||||
@@ -107,11 +205,6 @@ $alert-error-red: hsl(0, 80%, 40%);
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .browser-alert .error::before {
 | 
					 | 
				
			||||||
        content: "Browser Error: ";
 | 
					 | 
				
			||||||
        font-weight: 600;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* animation section */
 | 
					/* animation section */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -462,6 +462,7 @@ on a dark background, and don't change the dark labels dark either. */
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .alert-box .alert,
 | 
					    .alert-box .alert,
 | 
				
			||||||
 | 
					    .alert-box .stacktrace,
 | 
				
			||||||
    .alert.alert-error {
 | 
					    .alert.alert-error {
 | 
				
			||||||
        background-color: hsl(318, 12%, 21%);
 | 
					        background-color: hsl(318, 12%, 21%);
 | 
				
			||||||
        color: inherit;
 | 
					        color: inherit;
 | 
				
			||||||
@@ -472,6 +473,34 @@ on a dark background, and don't change the dark labels dark either. */
 | 
				
			|||||||
        color: 1px solid hsl(0, 75%, 65%);
 | 
					        color: 1px solid hsl(0, 75%, 65%);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .alert-box .stacktrace {
 | 
				
			||||||
 | 
					        color: hsl(314, 22%, 85%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .expand {
 | 
				
			||||||
 | 
					            color: hsl(318, 14%, 36%);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .subtle {
 | 
				
			||||||
 | 
					            color: hsl(314, 19%, 63%);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .code-context {
 | 
				
			||||||
 | 
					            color: hsl(314, 27%, 82%);
 | 
				
			||||||
 | 
					            background-color: hsl(312, 7%, 14%);
 | 
				
			||||||
 | 
					            box-shadow:
 | 
				
			||||||
 | 
					                inset 0px 11px 10px -10px hsl(0, 0%, 6%),
 | 
				
			||||||
 | 
					                inset 0px -11px 10px -10px hsl(0, 0%, 6%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .line-number {
 | 
				
			||||||
 | 
					                color: hsl(318, 14%, 44%);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .focus-line {
 | 
				
			||||||
 | 
					                background-color: hsl(307, 9%, 19%);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Popover: */
 | 
					    /* Popover: */
 | 
				
			||||||
    .hotspot.overlay .hotspot-popover,
 | 
					    .hotspot.overlay .hotspot-popover,
 | 
				
			||||||
    #hotspot_intro_reply_icon {
 | 
					    #hotspot_intro_reply_icon {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								static/templates/blueslip_stacktrace.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								static/templates/blueslip_stacktrace.hbs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					<div class="stacktrace-header">
 | 
				
			||||||
 | 
					    <div class="warning-symbol">
 | 
				
			||||||
 | 
					        <i class="fa fa-exclamation-triangle"></i>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="message"><strong>Error:</strong> {{ error }}</div>
 | 
				
			||||||
 | 
					    <div class="exit"></div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div class="stacktrace-content">
 | 
				
			||||||
 | 
					    {{#each stackframes}}
 | 
				
			||||||
 | 
					    <div data-full-path="{{ full_path }}" data-line-no="{{ line_number }}">
 | 
				
			||||||
 | 
					        <div class="stackframe">
 | 
				
			||||||
 | 
					            <i class="fa fa-caret-right expand"></i>
 | 
				
			||||||
 | 
					            <span class="subtle">at</span>
 | 
				
			||||||
 | 
					            {{#if function_name}}
 | 
				
			||||||
 | 
					            {{ function_name.scope }}<b>{{ function_name.name }}</b>
 | 
				
			||||||
 | 
					            {{/if}}
 | 
				
			||||||
 | 
					            <span class="subtle">{{ show_path }}:{{ line_number }}</span>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="code-context" style="display: none">
 | 
				
			||||||
 | 
					            <div class="code-context-content">
 | 
				
			||||||
 | 
					                {{~#each context~}}
 | 
				
			||||||
 | 
					                <div {{#if focus}}class="focus-line"{{/if}}><span class="line-number">{{ line_number }}</span> {{ line }}</div>
 | 
				
			||||||
 | 
					                {{~/each~}}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    {{/each}}
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@@ -26,4 +26,4 @@ LATEST_RELEASE_ANNOUNCEMENT = "https://blog.zulip.org/2019/03/01/zulip-2-0-relea
 | 
				
			|||||||
#   historical commits sharing the same major version, in which case a
 | 
					#   historical commits sharing the same major version, in which case a
 | 
				
			||||||
#   minor version bump suffices.
 | 
					#   minor version bump suffices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PROVISION_VERSION = '62.0'
 | 
					PROVISION_VERSION = '62.1'
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -915,6 +915,13 @@
 | 
				
			|||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@types/node" "*"
 | 
					    "@types/node" "*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"@types/jquery@^3.3.31":
 | 
				
			||||||
 | 
					  version "3.3.31"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.31.tgz#27c706e4bf488474e1cb54a71d8303f37c93451b"
 | 
				
			||||||
 | 
					  integrity sha512-Lz4BAJihoFw5nRzKvg4nawXPzutkv7wmfQ5121avptaSIXlDNJCUuxZxX/G+9EVidZGuO0UBlk+YjKbwRKJigg==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    "@types/sizzle" "*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@types/json-schema@^7.0.3":
 | 
					"@types/json-schema@^7.0.3":
 | 
				
			||||||
  version "7.0.3"
 | 
					  version "7.0.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"
 | 
					  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"
 | 
				
			||||||
@@ -953,6 +960,11 @@
 | 
				
			|||||||
    "@types/express-serve-static-core" "*"
 | 
					    "@types/express-serve-static-core" "*"
 | 
				
			||||||
    "@types/mime" "*"
 | 
					    "@types/mime" "*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"@types/sizzle@*":
 | 
				
			||||||
 | 
					  version "2.3.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
 | 
				
			||||||
 | 
					  integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@types/source-list-map@*":
 | 
					"@types/source-list-map@*":
 | 
				
			||||||
  version "0.1.2"
 | 
					  version "0.1.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
 | 
					  resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
 | 
				
			||||||
@@ -9353,7 +9365,7 @@ regenerate@^1.4.0:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
 | 
					  resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
 | 
				
			||||||
  integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
 | 
					  integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
regenerator-runtime@^0.13.2:
 | 
					regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.3:
 | 
				
			||||||
  version "0.13.3"
 | 
					  version "0.13.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5"
 | 
					  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5"
 | 
				
			||||||
  integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==
 | 
					  integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==
 | 
				
			||||||
@@ -10323,6 +10335,11 @@ source-map-url@^0.4.0:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
 | 
					  resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
 | 
				
			||||||
  integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
 | 
					  integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source-map@0.5.6:
 | 
				
			||||||
 | 
					  version "0.5.6"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
 | 
				
			||||||
 | 
					  integrity sha1-dc449SvwczxafwwRjYEzSiu19BI=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"source-map@>= 0.1.2":
 | 
					"source-map@>= 0.1.2":
 | 
				
			||||||
  version "0.7.3"
 | 
					  version "0.7.3"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
 | 
					  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
 | 
				
			||||||
@@ -10495,6 +10512,14 @@ stackframe@^1.1.0:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.0.tgz#e3fc2eb912259479c9822f7d1f1ff365bd5cbc83"
 | 
					  resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.0.tgz#e3fc2eb912259479c9822f7d1f1ff365bd5cbc83"
 | 
				
			||||||
  integrity sha512-Vx6W1Yvy+AM1R/ckVwcHQHV147pTPBKWCRLrXMuPrFVfvBUc3os7PR1QLIWCMhPpRg5eX9ojzbQIMLGBwyLjqg==
 | 
					  integrity sha512-Vx6W1Yvy+AM1R/ckVwcHQHV147pTPBKWCRLrXMuPrFVfvBUc3os7PR1QLIWCMhPpRg5eX9ojzbQIMLGBwyLjqg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					stacktrace-gps@^3.0.3:
 | 
				
			||||||
 | 
					  version "3.0.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.3.tgz#b89f84cc13bb925b96607e737b617c8715facf57"
 | 
				
			||||||
 | 
					  integrity sha512-51Rr7dXkyFUKNmhY/vqZWK+EvdsfFSRiQVtgHTFlAdNIYaDD7bVh21yBHXaNWAvTD+w+QSjxHg7/v6Tz4veExA==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    source-map "0.5.6"
 | 
				
			||||||
 | 
					    stackframe "^1.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
state-toggle@^1.0.0:
 | 
					state-toggle@^1.0.0:
 | 
				
			||||||
  version "1.0.2"
 | 
					  version "1.0.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.2.tgz#75e93a61944116b4959d665c8db2d243631d6ddc"
 | 
					  resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.2.tgz#75e93a61944116b4959d665c8db2d243631d6ddc"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user