Files
config-pacs-docker/nv/html/nv-nopdf/styles/packages/ohif_viewerbase.js
2025-02-26 14:49:25 +07:00

21487 lines
782 KiB
JavaScript

//////////////////////////////////////////////////////////////////////////
// //
// This is a generated file. You can view the original //
// source in your browser if your browser supports source maps. //
// Source maps are supported by all recent versions of Chrome, Safari, //
// and Firefox, and by Internet Explorer 11. //
// //
//////////////////////////////////////////////////////////////////////////
(function () {
/* Imports */
var Meteor = Package.meteor.Meteor;
var global = Package.meteor.global;
var meteorEnv = Package.meteor.meteorEnv;
var HTTP = Package.http.HTTP;
var $ = Package.jquery.$;
var jQuery = Package.jquery.jQuery;
var moment = Package['momentjs:moment'].moment;
var validate = Package.validatejs.validate;
var PersistentSession = Package['cultofcoders:persistent-session'].PersistentSession;
var cornerstone = Package['ohif:cornerstone'].cornerstone;
var cornerstoneMath = Package['ohif:cornerstone'].cornerstoneMath;
var cornerstoneTools = Package['ohif:cornerstone'].cornerstoneTools;
var cornerstoneWADOImageLoader = Package['ohif:cornerstone'].cornerstoneWADOImageLoader;
var dicomParser = Package['ohif:cornerstone'].dicomParser;
var dcmjs = Package['ohif:cornerstone'].dcmjs;
var meteorInstall = Package.modules.meteorInstall;
var meteorBabelHelpers = Package['babel-runtime'].meteorBabelHelpers;
var Promise = Package.promise.Promise;
var Symbol = Package['ecmascript-runtime-client'].Symbol;
var Map = Package['ecmascript-runtime-client'].Map;
var Set = Package['ecmascript-runtime-client'].Set;
var WebApp = Package.webapp.WebApp;
var Log = Package.logging.Log;
var Tracker = Package.deps.Tracker;
var Deps = Package.deps.Deps;
var Session = Package.session.Session;
var DDP = Package['ddp-client'].DDP;
var Mongo = Package.mongo.Mongo;
var Blaze = Package.ui.Blaze;
var UI = Package.ui.UI;
var Handlebars = Package.ui.Handlebars;
var Spacebars = Package.spacebars.Spacebars;
var Template = Package['templating-runtime'].Template;
var check = Package.check.check;
var Match = Package.check.Match;
var _ = Package.underscore._;
var Random = Package.random.Random;
var EJSON = Package.ejson.EJSON;
var LaunchScreen = Package['launch-screen'].LaunchScreen;
var HTML = Package.htmljs.HTML;
/* Package-scope variables */
var ProtocolEngine, dialogPolyfill;
var require = meteorInstall({"node_modules":{"meteor":{"ohif:viewerbase":{"client":{"components":{"basic":{"layout":{"template.layout.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/basic/layout/template.layout.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("layout");
Template["layout"] = new Template("Template.layout", (function() {
var view = this;
return Spacebars.include(view.lookupTemplate("yield"));
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"loadingText":{"template.loadingText.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/basic/loadingText/template.loadingText.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("loadingText");
Template["loadingText"] = new Template("Template.loadingText", (function() {
var view = this;
return HTML.Raw('<div class="loadingTextDiv">\n Loading... <i class="fa fa-spin fa-circle-o-notch fa-fw"></i>\n </div>');
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"errorText":{"template.errorText.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/basic/errorText/template.errorText.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("errorText");
Template["errorText"] = new Template("Template.errorText", (function() {
var view = this;
return HTML.DIV({
class: "errorTextDiv"
}, "\n Error: ", Blaze.View("lookup:error", function() {
return Spacebars.mustache(view.lookup("error"));
}), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"removableBackdrop":{"template.removableBackdrop.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/basic/removableBackdrop/template.removableBackdrop.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("removableBackdrop");
Template["removableBackdrop"] = new Template("Template.removableBackdrop", (function() {
var view = this;
return HTML.Raw('<div class="removableBackdrop noselect" oncontextmenu="return false;" unselectable="on" onselectstart="return false;">\n </div>');
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"aboutModal":{"template.aboutModal.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/basic/aboutModal/template.aboutModal.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("aboutModal");
Template["aboutModal"] = new Template("Template.aboutModal", (function() {
var view = this;
return Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("extend"), view.lookup("."), Spacebars.kw({
id: "aboutModal",
dialogClass: "modal-lg",
title: "About"
}));
}, function() {
return Spacebars.include(view.lookupTemplate("dialogSimple"), function() {
return [ "\n ", HTML.A({
target: "_blank",
class: "forkOnGithub",
href: function() {
return Spacebars.mustache(view.lookup("githubUrl"));
}
}, "\n ", HTML.IMG({
src: "https://camo.githubusercontent.com/365986a132ccd6a44c23a9169022c0b5c890c387/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67",
alt: "Fork me on GitHub",
"data-canonical-src": "https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png"
}), "\n "), "\n ", HTML.DIV({
class: "logo p-x-3 p-y-3 clearfix"
}, "\n ", HTML.SVG({
class: "logoImage pull-left"
}, "\n ", HTML.USE({
"xlink:href": function() {
return Spacebars.mustache(view.lookup("absoluteUrl"), "packages/ohif_viewerbase/assets/icons.svg#icon-ohif-logo");
}
}), "\n "), "\n ", HTML.A({
class: "logoText pull-left",
target: "_blank",
href: "http://ohif.org"
}, "\n Open Health Imaging Foundation DICOM Viewer\n "), "\n "), "\n ", HTML.DIV({
class: "p-x-1 p-y-1 m-y-2"
}, "\n ", HTML.A({
class: "btn btn-default inline",
target: "_blank",
href: "https://groups.google.com/forum/#!forum/cornerstone-platform"
}, "\n Visit the forum\n "), "\n ", HTML.A({
class: "btn btn-default inline",
target: "_blank",
href: "https://github.com/OHIF/Viewers/issues"
}, "\n Report an issue\n "), "\n "), "\n ", HTML.DIV({
class: "p-y-1 p-x-1"
}, "\n ", HTML.H3("Version Information"), "\n ", HTML.TABLE({
class: "table table-responsive"
}, "\n ", HTML.THEAD("\n ", HTML.TR("\n ", HTML.TH("Name"), "\n ", HTML.TH("Value"), "\n "), "\n "), "\n ", HTML.TBODY("\n ", HTML.TR("\n ", HTML.TD("Repository URL"), "\n ", HTML.TD("\n ", HTML.A({
target: "_blank",
href: function() {
return Spacebars.mustache(view.lookup("githubUrl"));
}
}, Blaze.View("lookup:githubUrl", function() {
return Spacebars.mustache(view.lookup("githubUrl"));
})), "\n "), "\n "), "\n ", HTML.TR("\n ", HTML.TD("Last Commit Hash"), "\n ", HTML.TD("\n ", HTML.A({
target: "_blank",
href: function() {
return [ Spacebars.mustache(view.lookup("githubUrl")), "/commit/", Spacebars.mustache(view.lookup("gitRev"), "long") ];
}
}, "\n ", Blaze.View("lookup:gitRev", function() {
return Spacebars.mustache(view.lookup("gitRev"), "long");
}), "\n "), "\n "), "\n "), "\n ", HTML.TR("\n ", HTML.TD("Latest Tag"), "\n ", HTML.TD("\n ", HTML.A({
target: "_blank",
href: function() {
return [ Spacebars.mustache(view.lookup("githubUrl")), "/releases/tag/", Spacebars.mustache(view.lookup("gitRev"), "tag") ];
}
}, "\n ", Blaze.View("lookup:gitRev", function() {
return Spacebars.mustache(view.lookup("gitRev"), "tag");
}), "\n "), "\n "), "\n "), "\n ", HTML.TR("\n ", HTML.TD("Branch"), "\n ", HTML.TD("\n ", HTML.A({
target: "_blank",
href: function() {
return [ Spacebars.mustache(view.lookup("githubUrl")), "/tree/", Spacebars.mustache(view.lookup("gitRev"), "branch") ];
}
}, "\n ", Blaze.View("lookup:gitRev", function() {
return Spacebars.mustache(view.lookup("gitRev"), "branch");
}), "\n "), "\n "), "\n "), "\n "), "\n "), "\n "), "\n " ];
});
});
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"aboutModal.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/basic/aboutModal/aboutModal.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.aboutModal.helpers({
githubUrl: function () {
return 'https://github.com/OHIF/Viewers';
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}}},"studyBrowser":{"studyBrowser":{"template.studyBrowser.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/studyBrowser/studyBrowser/template.studyBrowser.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("studyBrowser");
Template["studyBrowser"] = new Template("Template.studyBrowser", (function() {
var view = this;
return HTML.DIV({
class: "studyBrowser"
}, "\n ", HTML.DIV({
class: "scrollableStudyThumbnails"
}, "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(view.lookup("studies")),
_variable: "study"
};
}, function() {
return [ "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.dataMustache(view.lookup("sort"), Spacebars.dataMustache(view.lookup("studyThumbnails"), view.lookup("study")), view.lookup("thumbnailSortBy"), view.lookup("thumbnailSortType")),
_variable: "thumbnail"
};
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return {
thumbnail: Spacebars.call(view.lookup("thumbnail"))
};
}, function() {
return Spacebars.include(view.lookupTemplate("thumbnailEntry"));
}), "\n " ];
}), "\n " ];
}), "\n "), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"studyBrowser.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 1);
Template.studyBrowser.helpers({
studies: function () {
// @TypeSafeStudies
return OHIF.viewer.Studies.findAllBy({
selected: true
});
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"thumbnailEntry":{"template.thumbnailEntry.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/studyBrowser/thumbnailEntry/template.thumbnailEntry.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("thumbnailEntry");
Template["thumbnailEntry"] = new Template("Template.thumbnailEntry", (function() {
var view = this;
return Blaze.Let({
stack: function() {
return Spacebars.call(Spacebars.dot(view.lookup("."), "thumbnail", "stack"));
}
}, function() {
return [ "\n ", HTML.DIV({
class: function() {
return [ "thumbnailEntry noselect m-t-1 m-b-2 ", Spacebars.mustache(view.lookup("draggableClass")), " ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("isDisplaySetActive"), Spacebars.dot(view.lookup("stack"), "displaySetInstanceUid"), view.lookup("viewportIndex"));
}, function() {
return "active";
}) ];
}
}, "\n ", HTML.DIV({
class: "p-x-1"
}, "\n ", Blaze._TemplateWith(function() {
return {
thumbnail: Spacebars.call(view.lookup("thumbnail")),
currentStudy: Spacebars.call(view.lookup("currentStudy"))
};
}, function() {
return Spacebars.include(view.lookupTemplate("imageThumbnail"));
}), "\n "), "\n ", HTML.DIV({
class: function() {
return [ "seriesDetails flex-h m-x-1 ", Blaze.Unless(function() {
return Spacebars.call(Spacebars.dot(view.lookup("stack"), "seriesDescription"));
}, function() {
return "info-only";
}) ];
}
}, "\n ", HTML.DIV({
class: "seriesDescription flex-grow"
}, "\n ", Blaze.View("lookup:stack.seriesDescription", function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("stack"), "seriesDescription"));
}), "\n "), "\n ", HTML.DIV({
class: "seriesInformation"
}, "\n ", HTML.DIV({
class: "item item-series clearfix"
}, "\n ", HTML.DIV({
class: "icon"
}, "S:"), "\n ", HTML.DIV({
class: "value"
}, Blaze.View("lookup:stack.seriesNumber", function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("stack"), "seriesNumber"));
})), "\n "), "\n ", Blaze.Unless(function() {
return Spacebars.dataMustache(view.lookup("isUndefined"), view.lookup("instanceNumber"));
}, function() {
return [ "\n ", HTML.DIV({
class: "item item-series clearfix"
}, "\n ", HTML.DIV({
class: "icon"
}, "I:"), "\n ", HTML.DIV({
class: "value"
}, Blaze.View("lookup:instanceNumber", function() {
return Spacebars.mustache(view.lookup("instanceNumber"));
})), "\n "), "\n " ];
}), "\n ", HTML.DIV({
class: "item item-frames clearfix"
}, "\n ", HTML.DIV({
class: "icon"
}, HTML.DIV()), "\n ", HTML.DIV({
class: "value"
}, Blaze.View("lookup:stack.numImageFrames", function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("stack"), "numImageFrames"));
})), "\n "), "\n "), "\n "), "\n "), "\n " ];
});
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"thumbnailEntry.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 1);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 2);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 3);
var thumbnailDragHandlers;
module.watch(require("../../../lib/thumbnailDragHandlers"), {
thumbnailDragHandlers: function (v) {
thumbnailDragHandlers = v;
}
}, 4);
Template.thumbnailEntry.onCreated(function () {
var instance = Template.instance(); // Check if the thumbnails will be draggable or clickable
var isIndexUndefined = _.isUndefined(instance.data.viewportIndex);
instance.isDragAndDrop = isIndexUndefined && OHIF.uiSettings.leftSidebarDragAndDrop !== false;
});
Template.thumbnailEntry.events({
// Event handlers for drag and drop
'mousedown .thumbnailEntry': function (event, instance) {
var data = instance.data.thumbnail.stack;
if (!instance.isDragAndDrop || event.button !== 0) return;
thumbnailDragHandlers.thumbnailDragStartHandler(event, data);
},
'touchstart .thumbnailEntry': function (event, instance) {
var data = instance.data.thumbnail.stack;
if (!instance.isDragAndDrop) return;
thumbnailDragHandlers.thumbnailDragStartHandler(event, data);
},
'touchmove .thumbnailEntry': function (event, instance) {
if (!instance.isDragAndDrop) return;
thumbnailDragHandlers.thumbnailDragHandler(event);
},
'touchend .thumbnailEntry': function (event, instance) {
var data = instance.data.thumbnail.stack;
if (!instance.isDragAndDrop) return;
thumbnailDragHandlers.thumbnailDragEndHandler(event, data);
},
// Event handlers for click (quick switch)
'click .thumbnailEntry': function (event, instance) {
if (instance.isDragAndDrop) return; // Get the thumbnail stack data
var data = instance.data.thumbnail.stack; // Get the viewport index
var viewportIndex = instance.data.viewportIndex;
if (_.isUndefined(viewportIndex)) {
viewportIndex = Session.get('activeViewport') || 0;
} // Rerender the viewport using the clicked thumbnail data
OHIF.viewerbase.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, data);
},
// Event handlers for double click
'dblclick .thumbnailEntry': function (event, instance) {
if (!instance.isDragAndDrop) return; // Get the active viewport index and total number of viewports...
var viewportCount = OHIF.viewerbase.layoutManager.getNumberOfViewports();
var viewportIndex = Session.get('activeViewport') || 0;
if (viewportIndex >= viewportCount) {
viewportIndex = viewportCount > 0 ? viewportCount - 1 : 0;
} // Get the thumbnail stack data
var data = instance.data.thumbnail.stack; // Rerender the viewport using the clicked thumbnail data
OHIF.viewerbase.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, data);
}
});
Template.thumbnailEntry.helpers({
draggableClass: function () {
return Template.instance().isDragAndDrop ? 'draggable' : '';
},
instanceNumber: function () {
var thumbnail = Template.instance().data.thumbnail;
if (!thumbnail) {
return;
}
var stack = thumbnail.stack;
if (!stack) {
return;
} // No need to show instance number for single-frame images
if (!stack.isMultiFrame) {
return;
}
var firstImage = stack.images[0];
if (!firstImage) {
return;
}
return firstImage.instanceNumber;
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"imageThumbnail":{"template.imageThumbnail.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/studyBrowser/imageThumbnail/template.imageThumbnail.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("imageThumbnail");
Template["imageThumbnail"] = new Template("Template.imageThumbnail", (function() {
var view = this;
return HTML.DIV({
class: "imageThumbnail"
}, HTML.Raw('\n <div class="imageThumbnailCanvas">\n <img class="static-image">\n </div>\n '), HTML.DIV({
class: function() {
return [ "imageThumbnailLoadingIndicator\n thumbnailLoadingIndicator\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("isLoading"));
}, function() {
return "d-block";
}) ];
}
}, "\n ", HTML.P("Loading ", Blaze.View("lookup:percentComplete", function() {
return Spacebars.mustache(view.lookup("percentComplete"));
})), "\n "), "\n ", HTML.DIV({
class: function() {
return [ "imageThumbnailErrorLoadingIndicator\n thumbnailLoadingIndicator\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("hasLoadingError"));
}, function() {
return "d-block";
}) ];
}
}, "\n ", HTML.Raw("<p>Error</p>"), "\n "), "\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("showStackLoadingProgressBar"));
}, function() {
return [ "\n ", HTML.DIV({
class: "imageThumbnailProgressBar"
}, "\n ", HTML.DIV({
class: "imageThumbnailProgressBarInner",
style: function() {
return [ "width:", Spacebars.mustache(view.lookup("stackPercentComplete")), "%" ];
}
}), "\n "), "\n " ];
}), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"imageThumbnail.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/studyBrowser/imageThumbnail/imageThumbnail.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 1);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 2);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 3);
var cornerstone;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
}
}, 4);
/**
* Asynchronous wrapper around Cornerstone's renderToCanvas method.
*
* @param {HTMLElement} canvasElement An HTML <canvas> element
* @param {Image} image A Cornerstone Image
*
* @return {Promise} A promise tracking the progress of the rendering. Resolves empty.
*/
function renderAsync(canvasElement, image) {
return new Promise(function (resolve, reject) {
try {
cornerstone.renderToCanvas(canvasElement, image);
resolve();
} catch (error) {
reject(error);
}
});
}
Template.imageThumbnail.onCreated(function () {
var instance = Template.instance();
instance.isLoading = new ReactiveVar(false);
instance.hasLoadingError = new ReactiveVar(false); // Get the image ID for current thumbnail
instance.getThumbnailImageId = function () {
var settingPath = 'public.ui.useMiddleSeriesInstanceAsThumbnail';
var useMiddleFrame = OHIF.utils.ObjectPath.get(Meteor.settings, settingPath);
var stack = instance.data.thumbnail.stack;
var lastIndex = (stack.numImageFrames || stack.images.length || 1) - 1;
var imageIndex = useMiddleFrame ? Math.floor(lastIndex / 2) : 0;
var imageInstance;
if (stack.isMultiFrame) {
imageInstance = stack.images[0];
} else {
imageInstance = stack.images[imageIndex];
imageIndex = undefined;
}
return imageInstance.getImageId(imageIndex, true);
};
});
Template.imageThumbnail.onRendered(function () {
var instance = Template.instance(); // Declare DOM and jQuery objects
var $parent = instance.$('.imageThumbnail');
var $thumbnailElement = $parent.find('.imageThumbnailCanvas');
instance.refreshImage = function () {
var imageElement = $thumbnailElement.find('img').get(0); // Activate the loading state
instance.isLoading.set(true);
instance.hasLoadingError.set(false); // Clear the previous image
imageElement.removeAttribute('src'); // Define a handler for success on image load
var loadSuccess = function (image) {
// This is an off-screen canvas. It's used to get dataURL images by using
// cornerstone.renderToCanvas function.
var canvasElement = document.createElement('canvas');
canvasElement.width = 193;
canvasElement.height = 123; // Render the image to canvas to be able to get its dataURL
renderAsync(canvasElement, image).then(function () {
instance.isLoading.set(false);
imageElement.src = canvasElement.toDataURL('image/jpeg', 1);
});
}; // Define a handler for error on image load
var loadError = function () {
instance.isLoading.set(false);
instance.hasLoadingError.set(true);
}; // Call cornerstone image loader with the defined handlers
cornerstone.loadAndCacheImage(instance.imageId).then(loadSuccess, loadError);
}; // Run this computation every time the current study is changed
instance.autorun(function () {
// Check if there is a reactive var set for current study
if (instance.data.currentStudy) {
// Register a dependency from this computation on current study
instance.data.currentStudy.dep.depend();
} // Depend on external data and re-run this computation when it changes
Template.currentData(); // Get the image ID. If it is the same as the currently rendered imageId,
// refresh the image.
var imageId = instance.getThumbnailImageId();
if (imageId !== instance.imageId) {
instance.imageId = imageId;
instance.refreshImage();
}
});
});
Template.imageThumbnail.helpers({
// Executed every time the thumbnail image loading progress is changed
percentComplete: function () {
var instance = Template.instance(); // Get the encoded image ID for thumbnail
var encodedImageId = OHIF.string.encodeId(instance.imageId); // Register a dependency from this computation on Session key
var percentComplete = Session.get('CornerstoneThumbnailLoadProgress' + encodedImageId); // Return the complete percent amount of the image loading
if (percentComplete && percentComplete !== 100) {
return percentComplete + '%';
}
},
// Return how much the stack has already loaded
stackPercentComplete: function () {
var stack = Template.instance().data.thumbnail.stack;
var progress = Session.get("StackProgress:" + stack.displaySetInstanceUid);
return progress && progress.percentComplete;
},
showStackLoadingProgressBar: function () {
return OHIF.uiSettings.showStackLoadingProgressBar;
},
isLoading: function () {
return Template.instance().isLoading.get();
},
hasLoadingError: function () {
return Template.instance().hasLoadingError.get();
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}}},"viewer":{"imageViewerViewport":{"template.imageViewerViewport.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/imageViewerViewport/template.imageViewerViewport.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("imageViewerViewport");
Template["imageViewerViewport"] = new Template("Template.imageViewerViewport", (function() {
var view = this;
return [ HTML.Raw('<div class="imageViewerViewport" oncontextmenu="return false;" unselectable="on" onselectstart="return false;" tabindex="0">\n </div>\n <div class="viewportInstructions">\n Please drag a stack here to view images.\n </div>\n '), Spacebars.include(view.lookupTemplate("viewportOverlay")), "\n ", Spacebars.include(view.lookupTemplate("loadingIndicator")), "\n ", Spacebars.include(view.lookupTemplate("viewportOrientationMarkers")) ];
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"imageViewerViewport.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 1);
var Tracker;
module.watch(require("meteor/tracker"), {
Tracker: function (v) {
Tracker = v;
}
}, 2);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 3);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 4);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 5);
var cornerstone, cornerstoneTools;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
},
cornerstoneTools: function (v) {
cornerstoneTools = v;
}
}, 6);
var StackManager;
module.watch(require("../../../lib/StackManager"), {
StackManager: function (v) {
StackManager = v;
}
}, 7);
var setActiveViewport;
module.watch(require("../../../lib/setActiveViewport"), {
setActiveViewport: function (v) {
setActiveViewport = v;
}
}, 8);
var imageViewerViewportData;
module.watch(require("../../../lib/imageViewerViewportData"), {
imageViewerViewportData: function (v) {
imageViewerViewportData = v;
}
}, 9);
var updateCrosshairsSynchronizer;
module.watch(require("../../../lib/updateCrosshairsSynchronizer"), {
updateCrosshairsSynchronizer: function (v) {
updateCrosshairsSynchronizer = v;
}
}, 10);
var toolManager;
module.watch(require("../../../lib/toolManager"), {
toolManager: function (v) {
toolManager = v;
}
}, 11);
var updateOrientationMarkers;
module.watch(require("../../../lib/updateOrientationMarkers"), {
updateOrientationMarkers: function (v) {
updateOrientationMarkers = v;
}
}, 12);
var getInstanceClassDefaultViewport;
module.watch(require("../../../lib/instanceClassSpecificViewport"), {
getInstanceClassDefaultViewport: function (v) {
getInstanceClassDefaultViewport = v;
}
}, 13);
var OHIFError;
module.watch(require("../../../lib/classes/OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 14);
var allCornerstoneEvents = ['click', 'cornerstonetoolsmousedown', 'cornerstonetoolsmousedownactivate', 'cornerstonetoolsmouseclick', 'cornerstonetoolsmousedrag', 'cornerstonetoolsmouseup', 'cornerstonetoolsmousewheel', 'cornerstonetoolsdoubletap', 'cornerstonetoolstouchpress', 'cornerstonetoolsmultitouchstart', 'cornerstonetoolsmultitouchstartactive', 'cornerstonetoolsmultitouchdrag'];
var PLUGIN_CORNERSTONE = 'cornerstone';
/**
* This function loads a study series into a viewport element.
*
* @param data {object} Object containing the study, series, and viewport element to be used
*/
var loadDisplaySetIntoViewport = function (data, templateData) {
var wlPresets = OHIF.viewerbase.wlPresets;
OHIF.log.info('imageViewerViewport loadDisplaySetIntoViewport'); // Make sure we have all the data required to render the series
if (!data.study || !data.displaySet || !data.element) {
OHIF.log.warn('loadDisplaySetIntoViewport: No Study, Display Set, or Element provided');
return;
} // Get the current element and it's index in the list of all viewports
// The viewport index is often used to store information about a viewport element
var element = data.element;
var viewportIndex = templateData.viewportIndex;
var layoutManager = OHIF.viewerbase.layoutManager;
layoutManager.viewportData = layoutManager.viewportData || {};
layoutManager.viewportData[viewportIndex] = layoutManager.viewportData[viewportIndex] || {};
layoutManager.viewportData[viewportIndex].viewportIndex = viewportIndex; // Stop here if no data was defined for the viewer
if (!OHIF.viewer.data) return; // This data will be saved so that the viewport can be reloaded to the same state later
OHIF.viewer.data.loadedSeriesData[viewportIndex] = {}; // Create shortcut to displaySet
var displaySet = data.displaySet; // Get stack from Stack Manager
var stack = StackManager.findOrCreateStack(data.study, displaySet); // If is a clip, updates the global FPS for cine dialog
if (stack.isClip && stack.frameRate > 0) {
// Sets the global variable
OHIF.viewer.cine.framesPerSecond = parseFloat(stack.frameRate); // Update the cine dialog FPS
Session.set('UpdateCINE', Math.random());
} // Shortcut for array with image IDs
var imageIds = stack.imageIds; // Define the current image stack using the newly created image IDs
stack = {
currentImageIdIndex: data.currentImageIdIndex > 0 && data.currentImageIdIndex < imageIds.length ? data.currentImageIdIndex : 0,
imageIds: imageIds,
displaySetInstanceUid: data.displaySetInstanceUid
}; // Get the current image ID for the stack that will be rendered
var imageId = imageIds[stack.currentImageIdIndex]; // Save the current image ID inside the template data so it can be
// retrieved from the template helpers
templateData.imageId = imageId; // Save the current image ID inside the ViewportLoading object.
//
// The ViewportLoading object relates the viewport elements with whichever
// image is currently being loaded into them. This is useful so that we can
// place progress (download %) for each image inside the proper viewports.
window.ViewportLoading[viewportIndex] = imageId; // Enable Cornerstone for the viewport element
var options = {
renderer: OHIF.cornerstone.renderer
};
cornerstone.enable(element, options); // Get the handler functions that will run when loading has finished or thrown
// an error. These are used to show/hide loading / error text boxes on each viewport.
var endLoadingHandler = cornerstoneTools.loadHandlerManager.getEndLoadHandler();
var errorLoadingHandler = cornerstoneTools.loadHandlerManager.getErrorLoadingHandler(); // Get the current viewport settings
var viewport = cornerstone.getViewport(element);
var studyInstanceUid = data.studyInstanceUid,
seriesInstanceUid = data.seriesInstanceUid,
displaySetInstanceUid = data.displaySetInstanceUid,
currentImageIdIndex = data.currentImageIdIndex; // Store the current series data inside the Layout Manager
layoutManager.viewportData[viewportIndex] = {
imageId: imageId,
studyInstanceUid: studyInstanceUid,
seriesInstanceUid: seriesInstanceUid,
displaySetInstanceUid: displaySetInstanceUid,
currentImageIdIndex: currentImageIdIndex,
viewport: viewport || data.viewport,
viewportIndex: viewportIndex,
plugin: PLUGIN_CORNERSTONE
}; // Handle the case where the imageId isn't loaded correctly and the
// imagePromise returns undefined
// To test, uncomment the next line
// data.imageId = 'AfileThatDoesntWork'; // For testing only!
var imagePromise;
try {
imagePromise = cornerstone.loadAndCacheImage(imageId);
} catch (error) {
OHIF.log.info(error);
if (!imagePromise) {
errorLoadingHandler(element, imageId, error);
return;
}
} // Additional tasks for metadata provider. If using your own
// metadata provider, this may not be necessary.
// updateMetadata is important, though, to update image metadata that
// for any reason was missing some information such as rows, columns,
// sliceThickness, etc (See MetadataProvider class from ohif-cornerstone package)
var metadataProvider = OHIF.viewer.metadataProvider;
var isUpdateMetadataDefined = metadataProvider && typeof metadataProvider.updateMetadata === 'function'; // loadAndCacheImage configurable callbacks
var callbacks = imageViewerViewportData.callbacks; // Check if it has before loadAndCacheImage callback
if (typeof callbacks.before === 'function') {
OHIF.log.info('imageViewerViewport before loadAndCacheImage callback');
callbacks.before(imagePromise, templateData);
} // Start loading the image.
imagePromise.then(function (image) {
var enabledElement;
try {
enabledElement = cornerstone.getEnabledElement(element);
} catch (error) {
OHIF.log.warn('Viewport destroyed before loaded image could be displayed');
return;
} // Caches element's jQuery object
var $element = $(element); // Update the enabled element with the image and viewport data
// This is not usually necessary, but we need them stored in case
// a sopClassUid-specific viewport setting is present.
enabledElement.image = image;
enabledElement.viewport = cornerstone.getDefaultViewport(enabledElement.canvas, image);
if (isUpdateMetadataDefined) {
// Update the metaData for missing fields
metadataProvider.updateMetadata(image);
} // Check if there are default viewport settings for this sopClassUid
if (!displaySet.images || !displaySet.images.length) {
return;
}
var instance = displaySet.images[0];
var instanceClassViewport = getInstanceClassDefaultViewport(instance, enabledElement, image.imageId); // If there are sopClassUid-specific viewport settings, apply them
if (instanceClassViewport) {
cornerstone.displayImage(element, image, instanceClassViewport); // Mark that this element should not be fit to the window in the resize listeners
// TODO: Find another way to do this?
enabledElement.fitToWindow = false; // Resize the canvas to fit the current viewport element size.
cornerstone.resize(element, false);
} else if (data.viewport) {
// If there is a saved object containing Cornerstone viewport data
// (e.g. scale, invert, window settings) in the input data, apply it now.
cornerstone.displayImage(element, image, data.viewport); // Resize the canvas to fit the current viewport element size. Fit the displayed
// image to the canvas dimensions.
cornerstone.resize(element, true);
} else {
// If no saved viewport settings or modality-specific settings exists,
// display the loaded image in the viewport element with no loaded viewport
// settings.
cornerstone.displayImage(element, image); // Resize the canvas to fit the current viewport element size. Fit the displayed
// image to the canvas dimensions.
cornerstone.resize(element, true);
} // Set/store W/L preset data to Default on first display
wlPresets.updateElementWLPresetData(element); // Remove the data for this viewport from the ViewportLoading object
// This will stop the loading percentage complete from being displayed.
delete window.ViewportLoading[viewportIndex]; // Call the handler function that represents the end of the image loading phase
// (e.g. hide the progress text box)
endLoadingHandler(element, image); // Remove the 'empty' class from the viewport to hide any instruction text
element.classList.remove('empty'); // Hide the viewport instructions (i.e. 'Drag a stack here') and show
// the viewport overlay data.
$element.siblings('.viewportInstructions').hide();
$element.siblings('.imageViewerViewportOverlay').show(); // Add stack state managers for the stack tool, CINE tool, and reference lines
cornerstoneTools.addStackStateManager(element, ['stack', 'playClip', 'referenceLines']); // Enable orientation markers, if applicable
updateOrientationMarkers(element); // Clear any old stack data
cornerstoneTools.clearToolState(element, 'stack');
cornerstoneTools.addToolState(element, 'stack', stack); // Set the default CINE settings
var multiframeMetadata = instance.getDataProperty('multiframeMetadata');
var fps;
if (multiframeMetadata && multiframeMetadata.averageFrameRate > 0) {
fps = multiframeMetadata.averageFrameRate;
} else {
fps = OHIF.viewer.cine.framesPerSecond;
}
var cineToolData = {
loop: OHIF.viewer.cine.loop,
framesPerSecond: fps
};
cornerstoneTools.addToolState(element, 'playClip', cineToolData); // Autoplay datasets that have framerates set
if (multiframeMetadata && multiframeMetadata.isMultiframeImage && multiframeMetadata.averageFrameRate > 0) {
cornerstoneTools.playClip(element);
} // Enable mouse, mouseWheel, touch, and keyboard input on the element
cornerstoneTools.mouseInput.enable(element);
cornerstoneTools.touchInput.enable(element);
cornerstoneTools.mouseWheelInput.enable(element);
cornerstoneTools.keyboardInput.enable(element); // Use the tool manager to enable the currently active tool for this
// newly rendered element
var activeTool = toolManager.getActiveTool();
toolManager.setActiveTool(activeTool, [element]); // Define a function to run whenever the Cornerstone viewport is rendered
// (e.g. following a change of window or zoom)
var onImageRendered = function (event) {
var eventData = event.detail;
var viewport = eventData.viewport,
element = eventData.element; // Attention: Adding OHIF.log.info in this function may decrease the performance
// since this callback function is called multiple times (eg: when a tool is
// enabled/disabled -> cornerstone[toolName].tool.enable)
if (!layoutManager.viewportData[viewportIndex]) {
OHIF.log.warn("onImageRendered: LayoutManager has no viewport data for this viewport index?: " + viewportIndex);
} // Use Session to trigger reactive updates in the viewportOverlay helper functions
// This lets the viewport overlay always display correct window / zoom values
Session.set('CornerstoneImageRendered' + viewportIndex, Math.random()); // Save the current viewport into the OHIF.viewer.data global variable
layoutManager.viewportData[viewportIndex].viewport = viewport;
OHIF.viewer.data.loadedSeriesData[viewportIndex].viewport = viewport; // Update the W/L Preset data, if necessary
wlPresets.updateElementWLPresetData(element); // Check if it has onImageRendered loadAndCacheImage callback
if (typeof callbacks.onImageRendered === 'function') {
callbacks.onImageRendered(event, eventData, viewportIndex, templateData);
}
}; // Attach the onImageRendered callback to the CornerstoneImageRendered event
element.removeEventListener('cornerstoneimagerendered', onImageRendered);
element.addEventListener('cornerstoneimagerendered', onImageRendered); // Set a random value for the Session variable in order to trigger an overlay update
Session.set('CornerstoneImageRendered' + viewportIndex, Math.random()); // Define a function to run whenever the Cornerstone viewport changes images
// (e.g. during scrolling)
var onNewImage = function (event) {
var eventData = event.detail; // Attention: Adding OHIF.log.info in this function may decrease the performance
// since this callback function is called multiple times (eg: when a tool is
// enabled/disabled -> cornerstone[toolName].tool.enable)
if (isUpdateMetadataDefined) {
// Update the metaData for missing fields
metadataProvider.updateMetadata(eventData.enabledElement.image);
} // Update the templateData with the new imageId
// This allows the template helpers to update reactively
templateData.imageId = eventData.enabledElement.image.imageId;
Session.set('CornerstoneNewImage' + viewportIndex, Math.random());
layoutManager.viewportData[viewportIndex].imageId = eventData.enabledElement.image.imageId; // Get the element and stack data
var element = event.target;
var toolData = cornerstoneTools.getToolState(element, 'stack');
if (!toolData || !toolData.data || !toolData.data.length) {
return;
} // Update orientation markers in case new slices don't have the same orientation
// as the first slice
updateOrientationMarkers(element); // If this viewport is displaying a stack of images, save the current image
// index in the stack to the global OHIF.viewer.data object.
var stack = cornerstoneTools.getToolState(element, 'stack');
if (stack && stack.data.length && stack.data[0].imageIds.length > 1) {
var imageIdIndex = stack.data[0].imageIds.indexOf(templateData.imageId);
layoutManager.viewportData[viewportIndex].currentImageIdIndex = imageIdIndex;
OHIF.viewer.data.loadedSeriesData[viewportIndex].currentImageIdIndex = imageIdIndex;
}
var wlPresetData = cornerstone.getElementData(element, 'wlPreset');
var wlPresetDataName = wlPresetData && wlPresetData.name;
wlPresets.applyWLPreset(wlPresetDataName, element); // Check if it has onNewImage loadAndCacheImage callback
if (typeof callbacks.onNewImage === 'function') {
callbacks.onNewImage(event, eventData, viewportIndex, templateData);
}
}; // Attach the onNewImage callback to the CornerstoneNewImage event
element.removeEventListener('cornerstonenewimage', onNewImage);
element.addEventListener('cornerstonenewimage', onNewImage); // Set a random value for the Session variable in order to trigger an overlay update
Session.set('CornerstoneNewImage' + viewportIndex, Math.random());
var onStackScroll = function () {
// Attention: Adding OHIF.log.info in this function may decrease the performance
// since this callback function is called multiple times (eg: when a tool is
// enabled/disabled -> cornerstone[toolName].tool.enable)
// Update the imageSlider value
Session.set('CornerstoneNewImage' + viewportIndex, Math.random());
};
element.removeEventListener('cornerstonestackscroll', onStackScroll);
if (stack.imageIds.length > 1) {
element.addEventListener('cornerstonestackscroll', onStackScroll);
} // Define a function to trigger an event whenever a new viewport is being used
// This is used to update the value of the "active viewport", when the user interacts
// with a new viewport element
var sendActivationTrigger = function (event) {
var eventData = event && event.detail; // Attention: Adding OHIF.log.info in this function decrease the performance
// since this callback function is called multiple times (eg: when a tool is
// enabled/disabled -> cornerstone[toolName].tool.enable)
// Reset the focus, even if we don't need to re-enable reference lines or prefetching
var element = eventData && eventData.element || event && event.currentTarget;
if (!element) return;
var $element = $(element); // Stop here if we don't have eventData set
if (!eventData) return; // Check if the current active viewport in the Meteor Session
// Is the same as the viewport in which the activation event was fired.
// If it was, no changes are necessary, so stop here.
var activeViewportIndex = Session.get('activeViewport');
if (viewportIndex === activeViewportIndex) return;
$element.focus();
OHIF.log.info('imageViewerViewport sendActivationTrigger'); // Otherwise, trigger an 'OHIFActivateViewport' event to be handled by the Template event
// handler
eventData.viewportIndex = viewportIndex;
var customEvent = $.Event('OHIFActivateViewport', eventData); // Need to overwrite the type set in the original event
customEvent.type = 'OHIFActivateViewport';
$element.trigger(customEvent, eventData);
}; // Handle mouseenter event to send viewport activation trigger only if there is no focused dropdown
var onMouseEnter = function () {
if ($(':focus').closest('.dropdown').length) return;
sendActivationTrigger();
}; // Attach the sendActivationTrigger function to all of the Cornerstone interaction events
allCornerstoneEvents.forEach(function (eventType) {
element.removeEventListener(eventType, sendActivationTrigger);
element.addEventListener(eventType, sendActivationTrigger);
});
$element.off('mouseenter', onMouseEnter);
$element.on('mouseenter', onMouseEnter);
OHIF.viewer.data.loadedSeriesData = layoutManager.viewportData; // Check if image plane (orientation / location) data is present for the current image
var imagePlane = cornerstone.metaData.get('imagePlane', image.imageId);
if (imagePlane && imagePlane.frameOfReferenceUID) {
// If it is, add this element to the global synchronizer...
OHIF.viewer.updateImageSynchronizer.add(element);
if (OHIF.viewer.refLinesEnabled) {
// ... and if reference lines are globally enabled, let cornerstoneTools know.
cornerstoneTools.referenceLines.tool.enable(element, OHIF.viewer.updateImageSynchronizer);
} // If the crosshairs tool is active, update the synchronizer
// that is used for its synchronized viewport updating.
// This is necessary if this new image shares a frame of reference
// with currently displayed images
if (activeTool === 'crosshairs') {
updateCrosshairsSynchronizer(imagePlane.frameOfReferenceUID);
}
} // Set the active viewport based on the Session variable
// This is done to ensure that the active element has the current
// focus, so that keyboard events are triggered.
if (viewportIndex === Session.get('activeViewport')) {
var viewportContainer = $element.parents('.viewportContainer');
setActiveViewport(viewportContainer);
} // Run any renderedCallback that exists in the data context
if (data.renderedCallback && typeof data.renderedCallback === 'function') {
data.renderedCallback(element);
} // Check if it has after loadAndCacheImage callback
if (typeof callbacks.after === 'function') {
OHIF.log.info('imageViewerViewport after callback');
callbacks.after(image, templateData, element);
}
}, function (error) {
// If something goes wrong while loading the image, fire the error handler.
errorLoadingHandler(element, imageId, error);
});
};
/**
* This function sets the display set for the study and calls LoadDisplaySetIntoViewport function
*
* @param data includes study data
* @param displaySetInstanceUid Display set information which is loaded in Template
* @param templateData currentData of Template
*
*/
var setDisplaySet = function (data, displaySetInstanceUid, templateData) {
var study = data.study;
if (!study) {
throw new OHIFError('Study does not exist');
}
var displaySets = study.displaySets;
if (!displaySets.length) {
displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(study);
study.displaySets = displaySets;
study.setDisplaySets(displaySets);
study.forEachDisplaySet(function (displaySet) {
OHIF.viewerbase.stackManager.makeAndAddStack(study, displaySet);
});
}
if (!displaySets) {
throw new OHIFError('Study has no display sets');
}
displaySets.every(function (displaySet) {
if (displaySet.displaySetInstanceUid === displaySetInstanceUid) {
data.displaySet = displaySet;
return false;
}
return true;
}); // If we didn't find anything, stop here
if (!data.displaySet) {
data.displaySet = displaySets[0]; // throw new OHIFError('Display set not found in specified study!');
} // Otherwise, load pass the data object into loadSeriesIntoViewport
loadDisplaySetIntoViewport(data, templateData);
};
Meteor.startup(function () {
window.ViewportLoading = window.ViewportLoading || {};
toolManager.configureLoadProcess();
});
Template.imageViewerViewport.onRendered(function () {
var templateData = Template.currentData();
OHIF.log.info('imageViewerViewport onRendered'); // When the imageViewerViewport template is rendered
var element = this.find('.imageViewerViewport');
this.element = element;
this.$element = $(element); // Display the loading indicator for this element
this.$element.siblings('.imageViewerLoadingIndicator').css('display', 'block'); // Get the current active viewport index, if this viewport has the same index,
// add the CSS 'active' class to highlight this viewport.
var activeViewport = Session.get('activeViewport'); // Focus the viewport if it's the active one
if (templateData.viewportIndex === activeViewport) {
this.$element.focus();
}
var currentImageIdIndex = templateData.currentImageIdIndex;
var viewport = templateData.viewport,
studyInstanceUid = templateData.studyInstanceUid,
seriesInstanceUid = templateData.seriesInstanceUid,
renderedCallback = templateData.renderedCallback,
displaySetInstanceUid = templateData.displaySetInstanceUid;
if (!currentImageIdIndex) {
currentImageIdIndex = 0;
} // Calls extendData function to provide flexibility between systems
imageViewerViewportData.extendData(templateData); // Create a data object to pass to the series loading function (loadSeriesIntoViewport)
var data = {
element: element,
viewport: viewport,
currentImageIdIndex: currentImageIdIndex,
displaySetInstanceUid: displaySetInstanceUid,
studyInstanceUid: studyInstanceUid,
seriesInstanceUid: seriesInstanceUid,
renderedCallback: renderedCallback,
activeViewport: activeViewport
}; // If no displaySetInstanceUid was supplied, display the drag/drop
// instructions and then stop here since we don't know what to display in the viewport.
if (!displaySetInstanceUid) {
element.classList.add('empty');
this.$element.siblings('.imageViewerLoadingIndicator').css('display', 'none');
this.$element.siblings('.viewportInstructions').show();
return;
} // @TypeSafeStudies
var study = OHIF.viewer.Studies.findBy({
studyInstanceUid: studyInstanceUid
});
data.study = study;
setDisplaySet(data, displaySetInstanceUid, templateData); // Double click event handlers to handle viewport enlargement
function doubleClickHandler(event) {
var $element = $(this);
var layoutManager = OHIF.viewerbase.layoutManager;
var $viewports = $('.imageViewerViewport');
$element.trigger('ohif.viewer.viewport.toggleEnlargement'); // Get the double clicked viewport index
var viewportIndex = $viewports.index(event.currentTarget); // Stop here if there's only one viewport
if (!layoutManager.isZoomed && $viewports.length <= 1) return; // Enlarge the double clicked viewport
layoutManager.toggleEnlargement(viewportIndex); // Wait for DOM re-rendering and update the active viewport
Tracker.afterFlush(function () {
var viewportIndexToZoom; // Check if the viewer is zoomed
if (layoutManager.isZoomed) {
// Set the active viewport as the only one visible
viewportIndexToZoom = 0;
} else {
// Set the active viewport as the previous zoomed viewport
viewportIndexToZoom = layoutManager.zoomedViewportIndex || 0;
} // Set zoomed viewport as active...
var viewportContainer = $('.viewportContainer').get(viewportIndexToZoom);
setActiveViewport(viewportContainer);
});
}
var doubleClickEvents = ['cornerstonetoolsmousedoubleclick', 'cornerstonetoolsdoubletap'];
doubleClickEvents.forEach(function (eventType) {
element.removeEventListener(eventType, doubleClickHandler);
element.addEventListener(eventType, doubleClickHandler);
});
});
Template.imageViewerViewport.onDestroyed(function () {
OHIF.log.info('imageViewerViewport onDestroyed'); // When a viewport element is being destroyed
var element = this.find('.imageViewerViewport');
var $element = $(element);
if (!element || $element.hasClass('empty') || !$element.find('canvas').length) {
return;
} // Disable mouse functions
cornerstoneTools.mouseInput.disable(element);
cornerstoneTools.touchInput.disable(element);
cornerstoneTools.mouseWheelInput.disable(element);
OHIF.viewer.updateImageSynchronizer.remove(element); // Clear the stack prefetch data
var stackPrefetchData = cornerstoneTools.getToolState(element, 'stackPrefetch');
stackPrefetchData = [];
cornerstoneTools.stackPrefetch.disable(element); // Try to stop any currently playing clips
// Otherwise the interval will continuously throw errors
try {
var enabledElement = cornerstone.getEnabledElement(element);
if (enabledElement) {
cornerstoneTools.stopClip(element);
}
} catch (error) {
OHIF.log.warn(error);
} // Trigger custom Destroy Viewport event
// for compatibility with other systems
$element.trigger('OHIFDestroyedViewport'); // Disable the viewport element with Cornerstone
// This also triggers the removal of the element from all available
// synchronizers, such as the one used for reference lines.
cornerstone.disable(element);
});
Template.imageViewerViewport.events({
'OHIFActivateViewport .imageViewerViewport': function (event) {
OHIF.log.info('imageViewerViewport OHIFActivateViewport');
var viewportContainer = $(event.currentTarget).parents('.viewportContainer').get(0);
setActiveViewport(viewportContainer);
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"gridLayout":{"template.gridLayout.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/gridLayout/template.gridLayout.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("gridLayout");
Template["gridLayout"] = new Template("Template.gridLayout", (function() {
var view = this;
return HTML.DIV({
id: "imageViewerViewports"
}, "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(view.lookup("viewports")),
_variable: "viewport"
};
}, function() {
return [ "\n ", HTML.DIV({
class: function() {
return [ "viewportContainer ", Spacebars.mustache(view.lookup("getClass"), view.lookup("@index")), " ", Spacebars.mustache(view.lookup("activeClass"), view.lookup("@index")) ];
},
style: function() {
return [ "height:", Spacebars.mustache(view.lookup("height")), "%;width:", Spacebars.mustache(view.lookup("width")), "%;" ];
}
}, "\n ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("eq"), Spacebars.dot(view.lookup("viewport"), "plugin"), "cornerstone");
}, function() {
return [ "\n ", HTML.DIV({
class: "removable"
}, "\n ", Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("clone"), view.lookup("viewport"));
}, function() {
return Spacebars.include(view.lookupTemplate("imageViewerViewport"));
}), "\n "), "\n " ];
}, function() {
return [ "\n ", HTML.DIV({
class: function() {
return [ "viewport-plugin-", Spacebars.mustache(Spacebars.dot(view.lookup("viewport"), "plugin")) ];
},
style: "height:100%; width: 100%"
}, "\n "), "\n " ];
}), "\n ", Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({
viewport: view.lookup("viewport"),
viewportIndex: view.lookup("@index")
}));
}, function() {
return Spacebars.include(view.lookupTemplate("seriesQuickSwitch"));
}), "\n "), "\n " ];
}), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"gridLayout.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/gridLayout/gridLayout.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 1);
var TOP_CLASS = 'top';
var BOTTOM_CLASS = 'bottom';
var MIDDLE_CLASS = 'middle';
Template.gridLayout.helpers({
// Get the height percentage for each viewport
height: function () {
var instance = Template.instance();
var rows = instance.data.rows || 1;
return 100 / rows;
},
// Get the width percentage for each viewport
width: function () {
var instance = Template.instance();
var columns = instance.data.columns || 1;
return 100 / columns;
},
// Get class for each viewport, so each app
// using ohif-viewerbase can style on their own
getClass: function (index) {
var rows = this.rows,
columns = this.columns;
if (rows === 1) {
return TOP_CLASS + " " + BOTTOM_CLASS;
}
var actualRow = Math.floor(index / columns);
if (actualRow === 0) {
return TOP_CLASS;
}
if (actualRow + 1 === rows) {
return BOTTOM_CLASS;
}
return MIDDLE_CLASS;
},
activeClass: function (index) {
if (Session.get('activeViewport') === index) {
return 'active';
}
;
},
// Return the viewports list
viewports: function () {
var instance = Template.instance();
var rows = instance.data.rows;
var columns = instance.data.columns;
var numViewports = rows * columns;
var viewportData = instance.data.viewportData;
var numViewportsWithData = viewportData.length; // Check if the viewportData length is different from the given
if (numViewportsWithData < numViewports) {
// Add the missing viewports
var difference = numViewports - numViewportsWithData;
for (var i = 0; i < difference; i++) {
viewportData.push({
viewportIndex: numViewportsWithData + i + 1,
rows: rows,
columns: columns
});
}
} else if (numViewportsWithData > numViewports) {
// Remove the additional viewports
return viewportData.slice(0, numViewports);
} // Return the viewports
return viewportData;
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"loadingIndicator":{"template.loadingIndicator.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/loadingIndicator/template.loadingIndicator.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("loadingIndicator");
Template["loadingIndicator"] = new Template("Template.loadingIndicator", (function() {
var view = this;
return [ HTML.DIV({
class: "imageViewerLoadingIndicator loadingIndicator"
}, "\n ", HTML.DIV({
class: "indicatorContents"
}, "\n ", HTML.P("Loading... ", HTML.Raw('<i class="fa fa-spin fa-circle-o-notch fa-fw"></i>'), " ", Blaze.View("lookup:percentComplete", function() {
return Spacebars.mustache(view.lookup("percentComplete"));
})), "\n "), "\n "), HTML.Raw('\n <div class="imageViewerErrorLoadingIndicator loadingIndicator">\n <div class="indicatorContents">\n <h4>Error Loading Image</h4>\n <p class="description">An error has occurred.</p>\n <p class="details"></p>\n </div>\n </div>') ];
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"loadingIndicator.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/loadingIndicator/loadingIndicator.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 1);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 2);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 3);
Meteor.startup(function () {
// This checking is necessary because cornerstoneTools may not have some tools available.
// Example: when an app defines its own cornerstone's lib versions, so it
// uses only ohif-viewerbase and not ohif-cornerstone and those libs are added later.
if (cornerstoneTools.loadHandlerManager) {
cornerstoneTools.loadHandlerManager.setStartLoadHandler(startLoadingHandler);
cornerstoneTools.loadHandlerManager.setEndLoadHandler(doneLoadingHandler);
cornerstoneTools.loadHandlerManager.setErrorLoadingHandler(errorLoadingHandler);
}
});
var loadHandlerTimeout;
var startLoadingHandler = function (element) {
clearTimeout(loadHandlerTimeout);
loadHandlerTimeout = setTimeout(function () {
console.log('startLoading');
var elem = $(element);
elem.siblings('.imageViewerErrorLoadingIndicator').css('display', 'none');
elem.find('canvas').not('.magnifyTool').addClass('faded');
elem.siblings('.imageViewerLoadingIndicator').css('display', 'block');
}, OHIF.viewer.loadIndicatorDelay);
};
var doneLoadingHandler = function (element) {
clearTimeout(loadHandlerTimeout);
var elem = $(element);
elem.siblings('.imageViewerErrorLoadingIndicator').css('display', 'none');
elem.find('canvas').not('.magnifyTool').removeClass('faded');
elem.siblings('.imageViewerLoadingIndicator').css('display', 'none');
};
var errorLoadingHandler = function (element, imageId, error, source) {
clearTimeout(loadHandlerTimeout);
var elem = $(element); // Could probably chain all of these, but this is more readable
elem.find('canvas').not('.magnifyTool').removeClass('faded');
elem.siblings('.imageViewerLoadingIndicator').css('display', 'none'); // Don't display errors from the stackPrefetch tool
if (source === 'stackPrefetch') {
return;
}
var errorLoadingIndicator = elem.siblings('.imageViewerErrorLoadingIndicator');
errorLoadingIndicator.css('display', 'block'); // This is just used to expand upon some error messages that are sent
// when things fail. An example is a network error throwing the error
// which is only described as "network".
var errorDetails = {
network: 'A network error has occurred' // We need to expand this further when we see more obscure error messages
};
if (errorDetails.hasOwnProperty(error)) {
error = errorDetails[error];
}
errorLoadingIndicator.find('.description').text("An error has occurred while loading image: " + imageId);
if (error) {
errorLoadingIndicator.find('.details').text("Details: " + error);
}
};
Template.loadingIndicator.helpers({
'percentComplete': function () {
var percentComplete = Session.get('CornerstoneLoadProgress' + this.viewportIndex);
if (percentComplete && percentComplete !== 100) {
return percentComplete + "%";
}
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"annotationDialogs":{"template.annotationDialogs.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/annotationDialogs/template.annotationDialogs.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("annotationDialogs");
Template["annotationDialogs"] = new Template("Template.annotationDialogs", (function() {
var view = this;
return [ HTML.getTag("dialog")({
id: "annotationDialog",
class: "annotationDialog noselect"
}, "\n ", HTML.H5("Enter your annotation"), "\n ", HTML.DIV({
class: "annotationTextInputOptions"
}, "\n ", HTML.LABEL({
for: "annotationTextInput"
}, "New label"), "\n ", HTML.INPUT({
name: "annotationTextInput",
class: "annotationTextInput",
type: "text",
tabindex: "-1",
autocomplete: "off"
}), "\n "), "\n ", HTML.A({
class: "annotationDialogConfirm btn btn-sm btn-primary"
}, "OK"), "\n "), "\n\n ", HTML.getTag("dialog")({
id: "relabelAnnotationDialog",
class: "annotationDialog noselect",
oncontextmenu: "return false"
}, "\n ", HTML.H5("Edit your annotation"), "\n ", HTML.DIV({
class: "annotationTextInputOptions"
}, "\n ", HTML.LABEL({
for: "annotationTextInput"
}, "New label"), "\n ", HTML.INPUT({
name: "annotationTextInput",
class: "annotationTextInput",
type: "text",
tabindex: "-1",
autocomplete: "off"
}), "\n "), "\n ", HTML.DIV("\n ", HTML.A({
class: "relabelRemove btn btn-sm btn-secondary"
}, "Remove marker"), "\n ", HTML.A({
class: "relabelConfirm btn btn-sm btn-primary"
}, "OK"), "\n "), "\n ") ];
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"annotationDialogs.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/annotationDialogs/annotationDialogs.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.annotationDialogs.onRendered(function () {
var instance = Template.instance();
var dialogIds = ['annotationDialog', 'relabelAnnotationDialog'];
dialogIds.forEach(function (id) {
var dialog = instance.$('#' + id);
dialog.draggable();
dialogPolyfill.registerDialog(dialog.get(0));
});
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"viewportOrientationMarkers":{"template.viewportOrientationMarkers.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/viewportOrientationMarkers/template.viewportOrientationMarkers.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("viewportOrientationMarkers");
Template["viewportOrientationMarkers"] = new Template("Template.viewportOrientationMarkers", (function() {
var view = this;
return HTML.Raw('<div class="viewportOrientationMarkers noselect">\n <div class="topMid orientationMarker">\n </div>\n <div class="leftMid orientationMarker">\n </div>\n </div>');
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"viewportOverlay":{"template.viewportOverlay.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/viewportOverlay/template.viewportOverlay.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("viewportOverlay");
Template["viewportOverlay"] = new Template("Template.viewportOverlay", (function() {
var view = this;
return HTML.DIV({
class: function() {
return [ "imageViewerViewportOverlay noselect ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("gt"), view.lookup("numImages"), 1);
}, function() {
return "controlsVisible";
}) ];
}
}, "\n ", Blaze.Unless(function() {
return Spacebars.call(view.lookup("tagDisplaySpecified"));
}, function() {
return [ "\n ", HTML.DIV({
class: "topleft dicomTag"
}, "\n ", HTML.DIV(Blaze.View("lookup:formatPN", function() {
return Spacebars.mustache(view.lookup("formatPN"), view.lookup("patientName"));
})), "\n ", HTML.DIV(Blaze.View("lookup:patientId", function() {
return Spacebars.mustache(view.lookup("patientId"));
})), "\n ", HTML.DIV({
class: "priorIndicator"
}, Blaze.View("lookup:prior", function() {
return Spacebars.mustache(view.lookup("prior"));
})), "\n "), "\n ", HTML.DIV({
class: "topright dicomTag"
}, "\n ", HTML.DIV(Blaze.View("lookup:studyDescription", function() {
return Spacebars.mustache(view.lookup("studyDescription"));
})), "\n ", HTML.DIV(Blaze.View("lookup:formatDA", function() {
return Spacebars.mustache(view.lookup("formatDA"), view.lookup("studyDate"));
}), " ", Blaze.View("lookup:formatTM", function() {
return Spacebars.mustache(view.lookup("formatTM"), view.lookup("studyTime"));
})), "\n "), "\n ", HTML.DIV({
class: "bottomright dicomTag"
}, "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.call(view.lookup("zoom"));
}, function() {
return [ "Zoom: ", Blaze.View("lookup:formatNumberPrecision", function() {
return Spacebars.mustache(view.lookup("formatNumberPrecision"), view.lookup("zoom"), 0);
}), "%" ];
})), "\n ", HTML.DIV({
class: "compressionIndicator"
}, Blaze.View("lookup:compression", function() {
return Spacebars.mustache(view.lookup("compression"));
})), "\n ", HTML.DIV(Blaze.View("lookup:wwwc", function() {
return Spacebars.mustache(view.lookup("wwwc"));
})), "\n "), "\n ", HTML.DIV({
class: "bottomleft dicomTag"
}, "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.call(view.lookup("seriesNumber"));
}, function() {
return [ "Ser: ", Blaze.View("lookup:seriesNumber", function() {
return Spacebars.mustache(view.lookup("seriesNumber"));
}) ];
})), "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("gt"), view.lookup("numImages"), 1);
}, function() {
return [ "Img: ", Blaze.View("lookup:instanceNumber", function() {
return Spacebars.mustache(view.lookup("instanceNumber"));
}), " (", Blaze.View("lookup:imageIndex", function() {
return Spacebars.mustache(view.lookup("imageIndex"));
}), "/", Blaze.View("lookup:numImages", function() {
return Spacebars.mustache(view.lookup("numImages"));
}), ")" ];
})), "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.call(view.lookup("frameRate"));
}, function() {
return [ Blaze.View("lookup:formatNumberPrecision", function() {
return Spacebars.mustache(view.lookup("formatNumberPrecision"), view.lookup("frameRate"), 2);
}), " FPS" ];
})), "\n ", HTML.DIV(Blaze.View("lookup:imageDimensions", function() {
return Spacebars.mustache(view.lookup("imageDimensions"));
})), "\n ", HTML.DIV("\n ", HTML.SPAN(Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("isValidNumber"), view.lookup("location"));
}, function() {
return [ "Loc: ", Blaze.View("lookup:formatNumberPrecision", function() {
return Spacebars.mustache(view.lookup("formatNumberPrecision"), view.lookup("location"), 2);
}), " mm" ];
})), "\n ", HTML.SPAN(Blaze.If(function() {
return Spacebars.call(view.lookup("thickness"));
}, function() {
return [ "Thick: ", Blaze.View("lookup:formatNumberPrecision", function() {
return Spacebars.mustache(view.lookup("formatNumberPrecision"), view.lookup("thickness"), 2);
}), " mm" ];
})), "\n ", HTML.SPAN(Blaze.If(function() {
return Spacebars.call(view.lookup("spacingBetweenSlices"));
}, function() {
return [ "Spacing: ", Blaze.View("lookup:formatNumberPrecision", function() {
return Spacebars.mustache(view.lookup("formatNumberPrecision"), view.lookup("spacingBetweenSlices"), 2);
}), " mm" ];
})), "\n "), "\n ", HTML.DIV(Blaze.View("lookup:seriesDescription", function() {
return Spacebars.mustache(view.lookup("seriesDescription"));
})), "\n "), "\n " ];
}), "\n\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("tagDisplayRightOnly"));
}, function() {
return [ "\n ", HTML.DIV({
class: "topright dicomTag"
}, "\n ", HTML.DIV(Blaze.View("lookup:formatPN", function() {
return Spacebars.mustache(view.lookup("formatPN"), view.lookup("patientName"));
})), "\n ", HTML.DIV(Blaze.View("lookup:patientId", function() {
return Spacebars.mustache(view.lookup("patientId"));
})), "\n ", HTML.DIV({
class: "priorIndicator"
}, Blaze.View("lookup:prior", function() {
return Spacebars.mustache(view.lookup("prior"));
})), "\n ", HTML.DIV(Blaze.View("lookup:studyDescription", function() {
return Spacebars.mustache(view.lookup("studyDescription"));
})), "\n ", HTML.DIV(Blaze.View("lookup:formatDA", function() {
return Spacebars.mustache(view.lookup("formatDA"), view.lookup("studyDate"));
}), " ", Blaze.View("lookup:formatTM", function() {
return Spacebars.mustache(view.lookup("formatTM"), view.lookup("studyTime"));
})), "\n "), "\n ", HTML.DIV({
class: "bottomright dicomTag"
}, "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.call(view.lookup("seriesNumber"));
}, function() {
return [ "Ser: ", Blaze.View("lookup:seriesNumber", function() {
return Spacebars.mustache(view.lookup("seriesNumber"));
}) ];
})), "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("gt"), view.lookup("numImages"), 1);
}, function() {
return [ "Img: ", Blaze.View("lookup:instanceNumber", function() {
return Spacebars.mustache(view.lookup("instanceNumber"));
}), " (", Blaze.View("lookup:imageIndex", function() {
return Spacebars.mustache(view.lookup("imageIndex"));
}), "/", Blaze.View("lookup:numImages", function() {
return Spacebars.mustache(view.lookup("numImages"));
}), ")" ];
})), "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.call(view.lookup("frameRate"));
}, function() {
return [ Blaze.View("lookup:formatNumberPrecision", function() {
return Spacebars.mustache(view.lookup("formatNumberPrecision"), view.lookup("frameRate"), 2);
}), " FPS" ];
})), "\n ", HTML.DIV(Blaze.View("lookup:imageDimensions", function() {
return Spacebars.mustache(view.lookup("imageDimensions"));
})), "\n ", HTML.DIV(Blaze.View("lookup:seriesDescription", function() {
return Spacebars.mustache(view.lookup("seriesDescription"));
})), "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.call(view.lookup("zoom"));
}, function() {
return [ "Zoom: ", Blaze.View("lookup:formatNumberPrecision", function() {
return Spacebars.mustache(view.lookup("formatNumberPrecision"), view.lookup("zoom"), 0);
}), "%" ];
})), "\n ", HTML.DIV({
class: "compressionIndicator"
}, Blaze.View("lookup:compression", function() {
return Spacebars.mustache(view.lookup("compression"));
})), "\n ", HTML.DIV(Blaze.View("lookup:wwwc", function() {
return Spacebars.mustache(view.lookup("wwwc"));
})), "\n "), "\n " ];
}), "\n\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("tagDisplayLeftOnly"));
}, function() {
return [ "\n ", HTML.DIV({
class: "topleft dicomTag"
}, "\n ", HTML.DIV(Blaze.View("lookup:formatPN", function() {
return Spacebars.mustache(view.lookup("formatPN"), view.lookup("patientName"));
})), "\n ", HTML.DIV(Blaze.View("lookup:patientId", function() {
return Spacebars.mustache(view.lookup("patientId"));
})), "\n ", HTML.DIV({
class: "priorIndicator"
}, Blaze.View("lookup:prior", function() {
return Spacebars.mustache(view.lookup("prior"));
})), "\n ", HTML.DIV(Blaze.View("lookup:studyDescription", function() {
return Spacebars.mustache(view.lookup("studyDescription"));
})), "\n ", HTML.DIV(Blaze.View("lookup:formatDA", function() {
return Spacebars.mustache(view.lookup("formatDA"), view.lookup("studyDate"));
}), " ", Blaze.View("lookup:formatTM", function() {
return Spacebars.mustache(view.lookup("formatTM"), view.lookup("studyTime"));
})), "\n "), "\n ", HTML.DIV({
class: "bottomleft dicomTag"
}, "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.call(view.lookup("seriesNumber"));
}, function() {
return [ "Ser: ", Blaze.View("lookup:seriesNumber", function() {
return Spacebars.mustache(view.lookup("seriesNumber"));
}) ];
})), "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("gt"), view.lookup("numImages"), 1);
}, function() {
return [ "Img: ", Blaze.View("lookup:instanceNumber", function() {
return Spacebars.mustache(view.lookup("instanceNumber"));
}), " (", Blaze.View("lookup:imageIndex", function() {
return Spacebars.mustache(view.lookup("imageIndex"));
}), "/", Blaze.View("lookup:numImages", function() {
return Spacebars.mustache(view.lookup("numImages"));
}), ")" ];
})), "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.call(view.lookup("frameRate"));
}, function() {
return [ Blaze.View("lookup:formatNumberPrecision", function() {
return Spacebars.mustache(view.lookup("formatNumberPrecision"), view.lookup("frameRate"), 2);
}), " FPS" ];
})), "\n ", HTML.DIV(Blaze.View("lookup:imageDimensions", function() {
return Spacebars.mustache(view.lookup("imageDimensions"));
})), "\n ", HTML.DIV(Blaze.View("lookup:seriesDescription", function() {
return Spacebars.mustache(view.lookup("seriesDescription"));
})), "\n ", HTML.DIV(Blaze.If(function() {
return Spacebars.call(view.lookup("zoom"));
}, function() {
return [ "Zoom: ", Blaze.View("lookup:formatNumberPrecision", function() {
return Spacebars.mustache(view.lookup("formatNumberPrecision"), view.lookup("zoom"), 0);
}), "%" ];
})), "\n ", HTML.DIV({
class: "compressionIndicator"
}, Blaze.View("lookup:compression", function() {
return Spacebars.mustache(view.lookup("compression"));
})), "\n ", HTML.DIV(Blaze.View("lookup:wwwc", function() {
return Spacebars.mustache(view.lookup("wwwc"));
})), "\n "), "\n " ];
}), "\n\n ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("gt"), view.lookup("numImages"), 1);
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return {
imageIndex: Spacebars.call(view.lookup("imageIndex")),
numImages: Spacebars.call(view.lookup("numImages"))
};
}, function() {
return Spacebars.include(view.lookupTemplate("imageControls"));
}), "\n " ];
}), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"viewportOverlay.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/viewportOverlay/viewportOverlay.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 1);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 2);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 3);
var cornerstone;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
}
}, 4);
var viewportOverlayUtils;
module.watch(require("../../../lib/viewportOverlayUtils"), {
viewportOverlayUtils: function (v) {
viewportOverlayUtils = v;
}
}, 5);
var getElementIfNotEmpty;
module.watch(require("../../../lib/getElementIfNotEmpty"), {
getElementIfNotEmpty: function (v) {
getElementIfNotEmpty = v;
}
}, 6);
var getStackDataIfNotEmpty;
module.watch(require("../../../lib/getStackDataIfNotEmpty"), {
getStackDataIfNotEmpty: function (v) {
getStackDataIfNotEmpty = v;
}
}, 7);
Template.viewportOverlay.onCreated(function () {
var instance = Template.instance();
instance.getImageIndex = function () {
var stack = getStackDataIfNotEmpty(instance.data.viewportIndex);
if (!stack || stack.currentImageIdIndex === undefined) return;
return stack.currentImageIdIndex;
};
});
Template.viewportOverlay.helpers({
wwwc: function () {
Session.get('CornerstoneImageRendered' + this.viewportIndex);
var element = getElementIfNotEmpty(this.viewportIndex);
if (!element) {
return '';
}
var viewport = cornerstone.getViewport(element);
if (!viewport) {
return '';
}
return 'W ' + viewport.voi.windowWidth.toFixed(0) + ' L ' + viewport.voi.windowCenter.toFixed(0);
},
zoom: function () {
Session.get('CornerstoneImageRendered' + this.viewportIndex);
var element = getElementIfNotEmpty(this.viewportIndex);
if (!element) {
return;
}
var viewport = cornerstone.getViewport(element);
if (!viewport) {
return;
}
return viewport.scale * 100.0;
},
imageDimensions: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
var image = viewportOverlayUtils.getImage(this.viewportIndex);
if (!image) {
return '';
}
return image.width + ' x ' + image.height;
},
patientName: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getPatient.call(this, 'name');
},
patientId: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getPatient.call(this, 'id');
},
patientBirthDate: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getPatient.call(this, 'birthDate');
},
patientSex: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getPatient.call(this, 'sex');
},
studyDate: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getStudy.call(this, 'studyDate');
},
studyTime: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getStudy.call(this, 'studyTime');
},
studyDescription: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getStudy.call(this, 'studyDescription');
},
seriesDescription: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getSeries.call(this, 'seriesDescription');
},
frameRate: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
var frameTime = viewportOverlayUtils.getInstance.call(this, 'frameTime');
if (!frameTime) {
return;
}
var frameRate = 1000 / frameTime;
return frameRate.toFixed(1);
},
seriesNumber: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getSeries.call(this, 'seriesNumber');
},
instanceNumber: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getInstance.call(this, 'instanceNumber');
},
thickness: function () {
// Displays Slice Thickness (0018,0050)
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getInstance.call(this, 'sliceThickness');
},
location: function () {
// Displays Slice Location (0020,1041), if present.
// - Otherwise, displays Table Position (0018,9327)
// - TODO: Otherwise, displays a value derived from Image Position (Patient) (0020,0032)
Session.get('CornerstoneNewImage' + this.viewportIndex);
var sliceLocation = viewportOverlayUtils.getInstance.call(this, 'sliceLocation');
if (sliceLocation !== '') {
return sliceLocation;
}
var tablePosition = viewportOverlayUtils.getInstance.call(this, 'tablePosition');
if (tablePosition !== '') {
return tablePosition;
}
return viewportOverlayUtils.getInstance.call(this, 'imagePositionPatient');
},
spacingBetweenSlices: function () {
// Displays Spacing Between Slices (0018,0088), if present.
// TODO: Otherwise, displays a value derived from successive values
// of Image Position (Patient) (0020,0032) perpendicular to
// the Image Orientation (Patient) (0020,0037)
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getInstance.call(this, 'spacingBetweenSlices');
},
compression: function () {
// Displays whether or not lossy compression has been applied:
//
// - Checks Lossy Image Compression (0028,2110)
// - If so, displays the value of Lossy Image Compression Ratio (0028,2112)
// and Lossy Image Compression Method (0028,2114)
Session.get('CornerstoneNewImage' + this.viewportIndex);
if (!this.imageId) {
return false;
}
var instance = cornerstone.metaData.get('instance', this.imageId);
if (!instance) {
return '';
}
if (instance.lossyImageCompression === '01' && instance.lossyImageCompressionRatio !== '') {
var compressionMethod = instance.lossyImageCompressionMethod || 'Lossy: ';
var compressionRatio = parseFloat(instance.lossyImageCompressionRatio).toFixed(2);
return compressionMethod + compressionRatio + ' : 1';
}
return 'Lossless / Uncompressed';
},
tagDisplayLeftOnly: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getTagDisplay.call(this, 'side') === 'L';
},
tagDisplayRightOnly: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getTagDisplay.call(this, 'side') === 'R';
},
tagDisplaySpecified: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getTagDisplay.call(this, 'side');
},
imageNumber: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getInstance.call(this, 'number');
},
imageIndex: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
var imageIndex = Template.instance().getImageIndex();
return _.isUndefined(imageIndex) ? 0 : imageIndex + 1;
},
numImages: function () {
Session.get('CornerstoneNewImage' + this.viewportIndex);
var stack = getStackDataIfNotEmpty(this.viewportIndex);
if (!stack || !stack.imageIds) {
return;
}
return stack.imageIds.length;
},
prior: function () {
// This helper is updated whenever a new image is displayed in the viewport
Session.get('CornerstoneNewImage' + this.viewportIndex);
if (!this.imageId) {
return;
} // @TypeSafeStudies
// Make sure there are more than two studies loaded in the viewer
var viewportStudies = OHIF.viewer.Studies.all();
if (viewportStudies.length < 2) {
return;
} // Here we sort the collection in ascending order by study date, so
// that we can obtain the oldest study as the first element of the array
//
// TODO= Find out if we should encode studyDate as a Date in the OHIF.viewer.Studies Collection
var viewportStudiesArray = _.sortBy(viewportStudies, function (study) {
return viewportOverlayUtils.formatDateTime(study.studyDate, study.studyTime);
}); // Get study data
var study = cornerstone.metaData.get('study', this.imageId);
if (!study) {
return;
}
var oldestStudy = viewportStudiesArray[0];
if (viewportOverlayUtils.formatDateTime(study.studyDate, study.studyTime) <= viewportOverlayUtils.formatDateTime(oldestStudy.studyDate, oldestStudy.studyTime)) {
return 'Prior';
}
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"viewerMain":{"template.viewerMain.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/viewerMain/template.viewerMain.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("viewerMain");
Template["viewerMain"] = new Template("Template.viewerMain", (function() {
var view = this;
return HTML.Raw('<div class="viewerMain">\n <div id="layoutManagerTarget">\n </div>\n </div>');
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"viewerMain.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/viewerMain/viewerMain.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 1);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 2);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 3);
var unloadHandlers;
module.watch(require("../../../lib/unloadHandlers"), {
unloadHandlers: function (v) {
unloadHandlers = v;
}
}, 4);
var ResizeViewportManager;
module.watch(require("../../../lib/classes/ResizeViewportManager"), {
ResizeViewportManager: function (v) {
ResizeViewportManager = v;
}
}, 5);
var LayoutManager;
module.watch(require("../../../lib/classes/LayoutManager"), {
LayoutManager: function (v) {
LayoutManager = v;
}
}, 6);
var StudyPrefetcher;
module.watch(require("../../../lib/classes/StudyPrefetcher"), {
StudyPrefetcher: function (v) {
StudyPrefetcher = v;
}
}, 7);
var StudyLoadingListener;
module.watch(require("../../../lib/classes/StudyLoadingListener"), {
StudyLoadingListener: function (v) {
StudyLoadingListener = v;
}
}, 8);
Meteor.startup(function () {
window.ResizeViewportManager = window.ResizeViewportManager || new ResizeViewportManager(); // Set initial value for OHIFViewerMainRendered
// session variable. This can used in viewer main template
Session.set('OHIFViewerMainRendered', false);
});
Template.viewerMain.onCreated(function () {
// Attach the Window resize listener
// Don't use jQuery here. "window.onresize" will always be null
// If its necessary, check all the code for window.onresize getter
// and change it to jQuery._data(window, 'events')['resize'].
// Otherwise this function will be probably overrided.
// See cineDialog instance.setResizeHandler function
window.addEventListener('resize', window.ResizeViewportManager.getResizeHandler()); // Add beforeUnload event handler to check for unsaved changes
window.addEventListener('beforeunload', unloadHandlers.beforeUnload);
});
Template.viewerMain.onRendered(function () {
var instance = Template.instance();
var studies = instance.data.studies;
var parentElement = instance.$('#layoutManagerTarget').get(0);
var studyPrefetcher = StudyPrefetcher.getInstance();
instance.studyPrefetcher = studyPrefetcher;
instance.studyLoadingListener = StudyLoadingListener.getInstance();
instance.studyLoadingListener.clear();
instance.studyLoadingListener.addStudies(studies);
OHIF.viewerbase.layoutManager = new LayoutManager(parentElement, studies);
studyPrefetcher.setStudies(studies);
Session.set('OHIFViewerMainRendered', Math.random());
});
Template.viewerMain.onDestroyed(function () {
var instance = Template.instance();
OHIF.log.info('viewerMain onDestroyed'); // Remove the Window resize listener
window.removeEventListener('resize', window.ResizeViewportManager.getResizeHandler()); // Remove beforeUnload event handler...
window.removeEventListener('beforeunload', unloadHandlers.beforeUnload); // Destroy the synchronizer used to update reference lines
OHIF.viewer.updateImageSynchronizer.destroy();
delete OHIF.viewerbase.layoutManager;
ProtocolEngine = null;
Session.set('OHIFViewerMainRendered', false); // Stop prefetching when we close the viewer
instance.studyPrefetcher.destroy(); // Destroy stack loading listeners when we close the viewer
instance.studyLoadingListener.clear(); // Clear references to all stacks in the StackManager
OHIF.viewerbase.stackManager.clearStacks(); // @TypeSafeStudies
// Clears OHIF.viewer.Studies collection
OHIF.viewer.Studies.removeAll(); // @TypeSafeStudies
// Clears OHIF.viewer.StudyMetadataList collection
OHIF.viewer.StudyMetadataList.removeAll();
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"toolContextMenu":{"toolContextMenu.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/toolContextMenu/toolContextMenu.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 1);
var cornerstone, cornerstoneTools;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
},
cornerstoneTools: function (v) {
cornerstoneTools = v;
}
}, 2);
var toolManager;
module.watch(require("../../../lib/toolManager"), {
toolManager: function (v) {
toolManager = v;
}
}, 3);
var toolTypes = ['length', 'simpleAngle', 'probe', 'ellipticalRoi', 'rectangleRoi', 'arrowAnnotate'];
var TypeToLabelMap = {
length: 'Length',
simpleAngle: 'Angle',
probe: 'Probe',
ellipticalRoi: 'Elliptical ROI',
rectangleRoi: 'Rectangle ROI',
arrowAnnotate: 'Annotation'
};
var dropdownItems = [{
actionType: 'Delete',
action: function (_ref) {
var nearbyToolData = _ref.nearbyToolData,
eventData = _ref.eventData;
var element = eventData.element;
cornerstoneTools.removeToolState(element, nearbyToolData.toolType, nearbyToolData.tool);
cornerstone.updateImage(element);
}
}];
var getTypeText = function (toolData, actionType) {
var toolType = toolData.toolType;
var message = "" + TypeToLabelMap[toolType];
if (toolType === 'arrowAnnotate') {
message = message + " \"" + toolData.tool.text + "\"";
}
return actionType + " " + message;
};
var createDropdown = function (eventData) {
var isTouchEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var nearbyToolData = toolManager.getNearbyToolData(eventData.element, eventData.currentPoints.canvas, toolTypes); // Annotate tools for touch events already have a press handle to edit it, has a better UX for deleting it
if (isTouchEvent && nearbyToolData.toolType === 'arrowAnnotate') return;
if (nearbyToolData) {
dropdownItems.forEach(function (item) {
item.params = {
eventData: eventData,
nearbyToolData: nearbyToolData
};
item.text = getTypeText(nearbyToolData, item.actionType);
});
OHIF.ui.showDropdown(dropdownItems, {
menuClasses: 'dropdown-menu-left',
event: eventData.event
});
}
};
Template.viewerMain.events({
'cornerstonetoolsmouseclick .imageViewerViewport': function (event) {
var originalEvent = event.originalEvent;
var eventData = originalEvent.detail;
if (eventData.which === 3) {
createDropdown(eventData);
}
},
'cornerstonetoolstouchpress .imageViewerViewport': function (event) {
var originalEvent = event.originalEvent;
var eventData = originalEvent.detail;
createDropdown(eventData, true);
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"imageControls":{"template.imageControls.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/imageControls/template.imageControls.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("imageControls");
Template["imageControls"] = new Template("Template.imageControls", (function() {
var view = this;
return HTML.DIV({
class: "imageControls"
}, "\n ", HTML.DIV({
class: "scrollbar"
}, "\n ", HTML.INPUT({
class: "imageSlider",
type: "range",
min: "1",
value: function() {
return Spacebars.mustache(view.lookup("imageIndex"));
},
max: function() {
return Spacebars.mustache(view.lookup("numImages"));
}
}), "\n "), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"imageControls.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/imageControls/imageControls.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 1);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 2);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 3);
var setActiveViewport;
module.watch(require("../../../lib/setActiveViewport"), {
setActiveViewport: function (v) {
setActiveViewport = v;
}
}, 4);
var switchToImageByIndex;
module.watch(require("../../../lib/switchToImageByIndex"), {
switchToImageByIndex: function (v) {
switchToImageByIndex = v;
}
}, 5);
var slideTimeoutTime = 40;
var slideTimeout;
Template.imageControls.onRendered(function () {
var instance = Template.instance(); // Set the current imageSlider width to its parent's height
// (because webkit is stupid and can't style vertical sliders)
var $slider = instance.$('.imageSlider');
var $viewport = $slider.closest('.imageViewerViewportOverlay').siblings('.imageViewerViewport');
instance.handleResize = _.throttle(function () {
var viewportHeight = $viewport.height();
$slider.width(viewportHeight - 20);
}, 150);
instance.handleResize();
$(window).on('resize', instance.handleResize);
});
Template.imageControls.onDestroyed(function () {
var instance = Template.instance();
if (instance.handleResize) {
$(window).off('resize', instance.handleResize);
}
});
Template.imageControls.events({
'rescale .scrollbar': function (event, instance) {
instance.handleResize();
},
'keydown input[type=range]': function (event) {
// We don't allow direct keyboard up/down input on the
// image sliders since the natural direction is reversed (0 is at the top)
// Store the KeyCodes in an object for readability
var keys = {
DOWN: 40,
UP: 38
};
if (event.which === keys.DOWN) {
OHIF.commands.run('scrollDown');
event.preventDefault();
} else if (event.which === keys.UP) {
OHIF.commands.run('scrollUp');
event.preventDefault();
}
},
'input input[type=range], change input[type=range]': function (event) {
// Note that we throttle requests to prevent the
// user's ultrafast scrolling from firing requests too quickly.
clearTimeout(slideTimeout);
slideTimeout = setTimeout(function () {
// Using the slider in an inactive viewport
// should cause that viewport to become active
var $slider = $(event.currentTarget);
var viewportContainer = $slider.parents('.viewportContainer');
setActiveViewport(viewportContainer); // Subtract 1 here since the slider goes from 1 to N images
// But the stack indexing starts at 0
var newImageIdIndex = parseInt($slider.val(), 10) - 1;
switchToImageByIndex(newImageIdIndex);
}, slideTimeoutTime);
return false;
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"layoutButton":{"template.layoutButton.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/layoutButton/template.layoutButton.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("layoutButton");
Template["layoutButton"] = new Template("Template.layoutButton", (function() {
var view = this;
return HTML.DIV({
id: function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("."), "id"));
},
class: function() {
return [ "toolbarSectionButton rp-x-1 ", Spacebars.mustache(Spacebars.dot(view.lookup("."), "classes")), " ", Spacebars.mustache(view.lookup("activeClass")), " js-dropdown-toggle" ];
},
title: function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("."), "title"));
},
"data-target": "#layoutChooser"
}, "\n ", HTML.DIV({
class: "svgContainer"
}, "\n ", Blaze.If(function() {
return Spacebars.call(Spacebars.dot(view.lookup("."), "svgLink"));
}, function() {
return [ "\n ", HTML.SVG("\n ", HTML.USE({
"xlink:href": function() {
return Spacebars.mustache(view.lookup("absoluteUrl"), Spacebars.dot(view.lookup("."), "svgLink"));
}
}), "\n "), "\n " ];
}, function() {
return [ "\n ", HTML.I({
class: function() {
return Spacebars.mustache(view.lookup("iconClasses"));
}
}), "\n " ];
}), "\n "), "\n ", HTML.DIV({
class: "buttonLabel"
}, "\n ", Blaze.View("lookup:..title", function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("."), "title"));
}), "\n "), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"layoutButton.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/layoutButton/layoutButton.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 1);
var viewportUtils;
module.watch(require("../../../lib/viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 2);
Template.layoutButton.events({
// TODO: Check why 'click' event won't fire?
'mousedown .js-dropdown-toggle': function (event) {
// Select the button and it's target dropdown menu
var $button = $(event.currentTarget);
var $dropdown = $($button.data('target')); // Adjust the dropdown's CSS to properly place it on the page
$dropdown.css({
top: $button.offset().top + $button.outerHeight() + 'px',
left: $button.offset().left + 'px'
}); // Open or close the layout chooser dialog
viewportUtils.toggleDialog($dropdown);
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"layoutChooser":{"template.layoutChooser.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/layoutChooser/template.layoutChooser.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("layoutChooser");
Template["layoutChooser"] = new Template("Template.layoutChooser", (function() {
var view = this;
return HTML.DIV({
id: "layoutChooser",
class: "layoutChooser dialog-animated"
}, "\n ", HTML.TABLE("\n ", HTML.TR("\n ", HTML.TD(), "\n ", HTML.TD(), "\n ", HTML.TD(), "\n ", HTML.TD(), "\n "), "\n ", HTML.TR("\n ", HTML.TD(), "\n ", HTML.TD(), "\n ", HTML.TD(), "\n ", HTML.TD(), "\n "), "\n ", HTML.TR("\n ", HTML.TD(), "\n ", HTML.TD(), "\n ", HTML.TD(), "\n ", HTML.TD(), "\n "), "\n ", HTML.TR("\n ", HTML.TD(), "\n ", HTML.TD(), "\n ", HTML.TD(), "\n ", HTML.TD(), "\n "), "\n "), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"layoutChooser.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/layoutChooser/layoutChooser.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _this = this;
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 1);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 2);
module.watch(require("meteor/ohif:viewerbase"));
var viewportUtils;
module.watch(require("../../../lib/viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 3);
Template.layoutChooser.onRendered(function () {
var instance = Template.instance();
/**
* Adds the 'hover' class to cells above and to the left of the current cell
* This is used to "fill in" the grid that the user will change the layout to,
* if they click on a specific table cell.
*
* @param currentCell
*/
instance.highlightCells = function (currentCell) {
var cells = _this.$('.layoutChooser table td');
cells.removeClass('hover');
currentCell = _this.$(currentCell);
var table = currentCell.parents('.layoutChooser table').get(0);
var rowIndex = currentCell.closest('tr').index();
var columnIndex = currentCell.index(); // Loop through the table row by row
// and cell by cell to apply the highlighting
for (var i = table.rows.length - 1; i >= 0; i--) {
var row = table.rows[i];
if (i <= rowIndex) {
for (var j = row.cells.length - 1; j >= 0; j--) {
if (j <= columnIndex) {
var cell = row.cells[j];
cell.classList.add('hover');
}
}
}
}
}; // Refresh layout chooser highlighting based on current viewports state
instance.refreshHighlights = function () {
// Stop here if layoutManager is not defined yet
if (!OHIF.viewerbase.layoutManager) {
return;
} // Get the layout rows and columns amount
var info = OHIF.viewerbase.layoutManager.layoutProps; // get the limiter cell
var cell = instance.$('tr').eq(info.rows - 1).children().eq(info.columns - 1); // Highlight all cells before the limiter
instance.highlightCells(cell);
};
instance.autorun(function () {
// Run this computation every time the viewer layout is changed
Session.get('LayoutManagerUpdated');
instance.refreshHighlights();
});
});
Template.layoutChooser.events({
'touchstart .layoutChooser table td, mouseenter .layoutChooser table td': function (event, instance) {
instance.highlightCells(event.currentTarget);
},
'mouseleave .layoutChooser': function (event, instance) {
instance.refreshHighlights();
},
'click .layoutChooser table td': function (event, instance) {
var $currentCell = instance.$(event.currentTarget);
var rowIndex = $currentCell.closest('tr').index();
var columnIndex = $currentCell.index(); // Add 1 because the indices start from zero
var layoutProps = {
rows: rowIndex + 1,
columns: columnIndex + 1
};
OHIF.viewerbase.layoutManager.layoutTemplateName = 'gridLayout';
OHIF.viewerbase.layoutManager.layoutProps = layoutProps;
OHIF.viewerbase.layoutManager.updateViewports();
var $dropdown = instance.$('.layoutChooser');
viewportUtils.toggleDialog($dropdown);
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"cineDialog":{"template.cineDialog.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/cineDialog/template.cineDialog.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("cineDialog");
Template["cineDialog"] = new Template("Template.cineDialog", (function() {
var view = this;
return HTML.getTag("dialog")({
id: "cineDialog"
}, "\n ", Blaze._TemplateWith(function() {
return {
id: Spacebars.call("cineDialogForm"),
class: Spacebars.call(Spacebars.dataMustache(view.lookup("getClassNames"), "dialog-animated noselect")),
schema: Spacebars.call(Spacebars.dot(view.lookup("instance"), "schema")),
api: Spacebars.call(Spacebars.dot(view.lookup("instance"), "api"))
};
}, function() {
return Spacebars.include(view.lookupTemplate("form"), function() {
return [ "\n ", Blaze._TemplateWith(function() {
return {
key: Spacebars.call("intervalId")
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputHidden"));
}), "\n ", HTML.DIV({
class: "button-close-container"
}, "\n ", HTML.DIV({
class: "button-close"
}, HTML.SPAN({
"aria-hidden": "true"
}, "x")), "\n "), "\n ", HTML.DIV({
class: "cine-controls"
}, "\n ", HTML.DIV({
class: "btn-group"
}, "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("btn"),
action: Spacebars.call("cineFirst"),
title: Spacebars.call("Skip to first image"),
disabled: Spacebars.call(Spacebars.dataMustache(view.lookup("buttonDisabled")))
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return [ "\n ", HTML.I({
class: "fa fa-fast-backward"
}), "\n " ];
});
}), "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("btn"),
action: Spacebars.call("cinePrevious"),
title: Spacebars.call("Previous image"),
disabled: Spacebars.call(Spacebars.dataMustache(view.lookup("buttonDisabled")))
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return [ "\n ", HTML.I({
class: "fa fa-step-backward"
}), "\n " ];
});
}), "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call(Spacebars.dataMustache(view.lookup("concat"), "btn ", Spacebars.dataMustache(view.lookup("valueIf"), view.lookup("isPlaying"), "active", ""))),
action: Spacebars.call("cineToggle"),
title: Spacebars.call("Play / Stop"),
disabled: Spacebars.call(Spacebars.dataMustache(view.lookup("buttonDisabled")))
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return [ "\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("isPlaying"));
}, function() {
return [ "\n ", HTML.I({
class: "fa fa-fw fa-stop"
}), "\n " ];
}, function() {
return [ "\n ", HTML.I({
class: "fa fa-fw fa-play"
}), "\n " ];
}), "\n " ];
});
}), "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("btn"),
action: Spacebars.call("cineNext"),
title: Spacebars.call("Next image"),
disabled: Spacebars.call(Spacebars.dataMustache(view.lookup("buttonDisabled")))
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return [ "\n ", HTML.I({
class: "fa fa-step-forward"
}), "\n " ];
});
}), "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("btn"),
action: Spacebars.call("cineLast"),
title: Spacebars.call("Skip to last image"),
disabled: Spacebars.call(Spacebars.dataMustache(view.lookup("buttonDisabled")))
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return [ "\n ", HTML.I({
class: "fa fa-fast-forward"
}), "\n " ];
});
}), "\n "), "\n "), "\n ", HTML.DIV({
class: "cine-options"
}, "\n ", HTML.DIV({
class: "fps-section"
}, "\n ", Blaze._TemplateWith(function() {
return {
key: Spacebars.call("framesPerSecond"),
class: Spacebars.call("p-a-0"),
labelClass: Spacebars.call("form-group m-a-0"),
labelAsDiv: Spacebars.call(true)
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputRange"), function() {
return "\n ";
});
}), "\n "), "\n ", HTML.SPAN({
id: "fps"
}, Blaze.View("lookup:framerate", function() {
return Spacebars.mustache(view.lookup("framerate"));
}), " fps"), "\n "), "\n ", HTML.DIV({
class: "cine-navigation"
}, "\n ", HTML.DIV({
class: "btn-group"
}, "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("btn"),
disabled: Spacebars.call(Spacebars.dataMustache(view.lookup("displaySetDisabled"), false)),
action: Spacebars.call("displaySetPrevious"),
title: Spacebars.call("Previous display set")
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return [ "\n ", HTML.I({
class: "fa fa-toggle-up"
}), "\n " ];
});
}), "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("btn"),
disabled: Spacebars.call(Spacebars.dataMustache(view.lookup("displaySetDisabled"), true)),
action: Spacebars.call("displaySetNext"),
title: Spacebars.call("Next display set")
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return [ "\n ", HTML.I({
class: "fa fa-toggle-down"
}), "\n " ];
});
}), "\n "), "\n "), "\n " ];
});
}), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"cineDialog.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/cineDialog/cineDialog.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var SimpleSchema;
module.watch(require("meteor/aldeed:simple-schema"), {
SimpleSchema: function (v) {
SimpleSchema = v;
}
}, 1);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 2);
var Tracker;
module.watch(require("meteor/tracker"), {
Tracker: function (v) {
Tracker = v;
}
}, 3);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 4);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 5);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 6);
var cornerstoneTools;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstoneTools: function (v) {
cornerstoneTools = v;
}
}, 7);
var viewportUtils;
module.watch(require("../../../lib/viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 8);
var switchToImageRelative;
module.watch(require("../../../lib/switchToImageRelative"), {
switchToImageRelative: function (v) {
switchToImageRelative = v;
}
}, 9);
var switchToImageByIndex;
module.watch(require("../../../lib/switchToImageByIndex"), {
switchToImageByIndex: function (v) {
switchToImageByIndex = v;
}
}, 10);
Template.cineDialog.onCreated(function () {
var instance = Template.instance(); // Create the data schema for CINE controls
instance.schema = new SimpleSchema({
intervalId: {
type: Number,
optional: true
},
loop: {
type: Boolean,
label: 'Loop',
defaultValue: true
},
framesPerSecond: {
type: Number,
label: '',
defaultValue: 24,
min: 1,
max: 90,
optional: true
}
}); // Update the current viewport frame rate
instance.updateFramerate = function (rate) {
OHIF.viewer.cine.framesPerSecond = rate; // Update playClip toolData for this imageId
var element = viewportUtils.getActiveViewportElement();
if (!element) {
return;
}
var playClipData = cornerstoneTools.getToolState(element, 'playClip');
if (!playClipData || !playClipData.data || !playClipData.data.length) {
return;
} // A valid playClip data object is available.
playClipData = playClipData.data[0]; // If the movie is playing, stop/start to update the framerate
if (playClipData.intervalId !== void 0) {
cornerstoneTools.stopClip(element);
cornerstoneTools.playClip(element, OHIF.viewer.cine.framesPerSecond);
} else {
playClipData.framesPerSecond = OHIF.viewer.cine.framesPerSecond;
}
Session.set('UpdateCINE', Math.random());
}; // Define the actions API
instance.api = {
displaySetPrevious: function () {
return OHIF.viewerbase.layoutManager.moveDisplaySets(false);
},
displaySetNext: function () {
return OHIF.viewerbase.layoutManager.moveDisplaySets(true);
},
cineToggle: function () {
return viewportUtils.toggleCinePlay();
},
cineFirst: function () {
return switchToImageByIndex(0);
},
cineLast: function () {
return switchToImageByIndex(-1);
},
cinePrevious: function () {
return switchToImageRelative(-1);
},
cineNext: function () {
return switchToImageRelative(1);
},
cineSlowDown: function () {
var newValue = OHIF.viewer.cine.framesPerSecond - 1;
if (newValue > 0) {
instance.updateFramerate(newValue);
}
},
cineSpeedUp: function () {
var newValue = OHIF.viewer.cine.framesPerSecond + 1;
if (newValue <= 90) {
instance.updateFramerate(newValue);
}
}
}; // Run this computation every time the active viewport is changed
instance.autorun(function () {
Session.get('activeViewport');
Tracker.afterFlush(function () {
// Get the active viewportElement
var element = viewportUtils.getActiveViewportElement();
if (!element) {
return;
} // check if playClip tool has been initialized...
var playClipData = cornerstoneTools.getToolState(element, 'playClip');
if (!playClipData) {
return;
} // Get the cornerstone playClip tool data
var toolData = playClipData.data[0]; // Get the cine object
var cine = OHIF.viewer.cine; // replace the cine values with the tool data
_.extend(cine, toolData); // Set the defaults
cine.framesPerSecond = cine.framesPerSecond || 24;
cine.loop = _.isUndefined(cine.loop) ? true : cine.loop; // Set the updated data on the form inputs
var elementComponent = instance.$('form:first').data('component');
if (elementComponent) {
elementComponent.value(cine);
} // Update the session to refresh the framerate text
Session.set('UpdateCINE', Math.random());
});
});
/**
* Set/Reset Window resize handler. This function is a replacement for
* ... jQuery's on('resize', func) version which, for some unkown reason
* ... is currently not working for this portion of code.
* ... Further investigation is necessary.
*
* This happens because when an event is attached using jQuery's
* you can't get it using vanilla JavaScript, it returns null.
* You need to use jQuery for that. So, either you use vanilla JS or jQuery
* to get an element's event handler. See viewerMain for more details.
*/
instance.setResizeHandler = function (handler) {
if (typeof handler === 'function') {
var origHandler = window.onresize;
instance.origWindowResizeHandler = typeof origHandler === 'function' ? origHandler : null;
window.onresize = function (event) {
if (typeof origHandler === 'function') {
origHandler.call(window, event);
}
handler.call(window, event);
};
} else {
window.onresize = instance.origWindowResizeHandler || null;
window.origWindowResizeHandler = null;
}
};
/**
* Set optimal position for Cine dialog.
*/
instance.setOptimalPosition = function (event, options) {
var $viewer = $('#viewer');
var $toolbarElement = $('.toolbarSection .toolbarSectionTools:first');
var $cineDialog = $('#cineDialog');
$cineDialog.width($('#cineDialogForm').outerWidth());
if ($toolbarElement.length < 1 || $cineDialog.length < 1) {
return;
}
if ($cineDialog.data('wasDragged') || $cineDialog.data('wasBounded')) {
// restore original handler...
instance.setResizeHandler(null);
return;
}
var cineDialogSize = {
width: $cineDialog.outerWidth() || 0,
height: $cineDialog.outerHeight() || 0
};
var topLeftCoords = {
top: 0,
left: 0
};
var toolbarRect = {
offset: $toolbarElement.offset() || topLeftCoords,
width: $toolbarElement.outerWidth() || 0,
height: $toolbarElement.outerHeight() || 0
};
var cineDialogCoords = {
left: toolbarRect.offset.left + toolbarRect.width + 20,
top: toolbarRect.offset.top + toolbarRect.height - cineDialogSize.height
};
if (options) {
if (options.left) {
cineDialogCoords.left = options.left;
}
if (options.top) {
cineDialogCoords.top = options.top;
}
} // Check if it is out of screen
if (cineDialogCoords.top < 0) {
cineDialogCoords.top = 0;
} else if (cineDialogCoords.top + cineDialogSize.height > $viewer.height()) {
cineDialogCoords.top -= cineDialogCoords.top + cineDialogSize.height - $viewer.height();
}
if (cineDialogCoords.left < 0) {
cineDialogCoords.left = 0;
} else if (cineDialogCoords.left + cineDialogSize.width > $viewer.width()) {
cineDialogCoords.left -= cineDialogCoords.left + cineDialogSize.width - $viewer.width();
}
$cineDialog.css(cineDialogCoords);
};
});
Template.cineDialog.onRendered(function () {
var instance = Template.instance();
var $dialog = instance.$('#cineDialog');
var singleRowLayout = OHIF.uiSettings.displayEchoUltrasoundWorkflow; // set dialog in optimal position and make sure it continues in a optimal position...
// ... when the window has been resized
instance.setOptimalPosition(null, {
top: singleRowLayout ? 47 : 26
}); // The jQuery method does not seem to be working...
// ... $(window).resize(instance.setOptimalPosition)
// This requires additional investigation.
instance.setResizeHandler(instance.setOptimalPosition); // Make the CINE dialog bounded and draggable
$dialog.draggable({
defaultElementCursor: 'move'
}).bounded(); // Polyfill for older browsers
window.dialogPolyfill.registerDialog($dialog.get(0)); // Prevent dialog from being dragged when user clicks any button
var $controls = $dialog.find('.cine-navigation, .cine-controls, .cine-options');
$controls.on('mousedown touchstart', function (event) {
return event.stopPropagation();
});
});
Template.cineDialog.onDestroyed(function () {
var instance = Template.instance(); // remove resize handler...
instance.setResizeHandler(null);
});
Template.cineDialog.events({
'change [data-key=loop] input': function (event, instance) {
var element = viewportUtils.getActiveViewportElement();
OHIF.viewer.cine.loop = $(event.currentTarget).is(':checked'); // Update playClip tool data if available.
var playClipData = cornerstoneTools.getToolState(element, 'playClip');
if (playClipData && playClipData.data && playClipData.data.length > 0) {
playClipData.data[0].loop = OHIF.viewer.cine.loop;
}
},
'input [data-key=framesPerSecond] input, change [data-key=framesPerSecond] input': function (event, instance) {
// Update the FPS text onscreen
var rate = parseFloat($(event.currentTarget).val());
instance.updateFramerate(rate);
},
'click .button-close': function (event, instance) {
OHIF.commands.run('toggleCineDialog');
}
});
Template.cineDialog.helpers({
isPlaying: function () {
return viewportUtils.isPlaying();
},
framerate: function () {
Session.get('UpdateCINE');
return OHIF.viewer.cine.framesPerSecond.toFixed(1);
},
displaySetDisabled: function (isNext) {
Session.get('LayoutManagerUpdated'); // @TODO: Investigate why this is running while OHIF.viewerbase.layoutManager is undefined
if (!OHIF.viewerbase.layoutManager) {
return;
}
return !OHIF.viewerbase.layoutManager.canMoveDisplaySets(isNext) ? 'disabled' : '';
},
buttonDisabled: function () {
return viewportUtils.hasMultipleFrames();
},
getClassNames: function (baseClass) {
var style = OHIF.uiSettings.displayEchoUltrasoundWorkflow ? 'single' : 'double';
return baseClass + " " + style + "-row-style";
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"downloadDialog":{"template.downloadDialog.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/downloadDialog/template.downloadDialog.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("imageDownloadDialog");
Template["imageDownloadDialog"] = new Template("Template.imageDownloadDialog", (function() {
var view = this;
return Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("extend"), view.lookup("."), Spacebars.kw({
title: "Download High Quality Image",
class: "themed",
dialogClass: "modal-lg",
formClass: "form-themed",
confirmLabel: "Download Image",
confirmCallback: Spacebars.dot(view.lookup("instance"), "getConfirmCallback"),
cancelLabel: "Cancel",
id: "imageDownloadDialog",
schema: Spacebars.dot(view.lookup("instance"), "schema")
}));
}, function() {
return Spacebars.include(view.lookupTemplate("dialogForm"), function() {
return [ "\n ", HTML.H5("Please specify the dimensions, filename, and desired type for the output image."), "\n ", HTML.DIV({
class: "card-round"
}, "\n ", HTML.DIV({
class: "row m-t-2"
}, "\n ", HTML.DIV({
class: "col-lg-4"
}, "\n ", HTML.TABLE({
class: "full-width"
}, "\n ", HTML.TBODY("\n ", HTML.TR("\n ", HTML.TD({
class: "text-right p-r-1 nowrap"
}, "Image width (px)"), "\n ", HTML.TD(Blaze._TemplateWith(function() {
return {
key: Spacebars.call("width"),
min: Spacebars.call("1"),
max: Spacebars.call("16384")
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputNumber"));
})), "\n ", HTML.TD({
class: "p-l-1",
rowspan: "2"
}, "\n ", HTML.BUTTON({
class: function() {
return [ "btn btn-secondary js-keep-aspect ", Blaze.If(function() {
return Spacebars.call(view.lookup("keepAspect"));
}, function() {
return "active";
}) ];
},
title: "Keep aspect ratio"
}, "\n ", HTML.I({
class: function() {
return [ "fa fa-chain", Blaze.Unless(function() {
return Spacebars.call(view.lookup("keepAspect"));
}, function() {
return "-broken";
}) ];
}
}), "\n "), "\n "), "\n "), "\n ", HTML.TR("\n ", HTML.TD({
class: "text-right p-r-1 nowrap"
}, "Image height (px)"), "\n ", HTML.TD(Blaze._TemplateWith(function() {
return {
key: Spacebars.call("height"),
min: Spacebars.call("1"),
max: Spacebars.call("16384")
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputNumber"));
})), "\n "), "\n "), "\n "), "\n "), "\n ", HTML.DIV({
class: "col-lg-5"
}, "\n ", HTML.TABLE({
class: "full-width"
}, "\n ", HTML.TBODY("\n ", HTML.TR("\n ", HTML.TD({
class: "text-right p-r-1"
}, "File name"), "\n ", HTML.TD(Blaze._TemplateWith(function() {
return {
key: Spacebars.call("name")
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputText"));
})), "\n "), "\n ", HTML.TR("\n ", HTML.TD({
class: "text-right p-r-1"
}, "File type"), "\n ", HTML.TD(Blaze._TemplateWith(function() {
return {
key: Spacebars.call("type"),
hideSearch: Spacebars.call(true)
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputSelect"));
})), "\n "), "\n "), "\n "), "\n "), "\n ", HTML.DIV({
class: "col-lg-3"
}, "\n ", HTML.TABLE({
class: "full-width"
}, "\n ", HTML.TBODY("\n ", HTML.TR("\n ", HTML.TD({
class: "text-right",
colspan: "2"
}, Blaze._TemplateWith(function() {
return {
key: Spacebars.call("showAnnotations")
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputCheckbox"));
})), "\n "), "\n "), "\n "), "\n "), "\n "), "\n "), "\n ", HTML.DIV({
class: "viewport-element hidden"
}), "\n ", HTML.DIV({
class: "image-preview card-round m-t-2 text-center"
}, "\n ", HTML.H4({
class: "m-t-0"
}, "Image Preview"), "\n ", HTML.IMG({
class: "viewport-preview"
}), "\n "), "\n " ];
});
});
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"downloadDialog.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/downloadDialog/downloadDialog.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var Tracker;
module.watch(require("meteor/tracker"), {
Tracker: function (v) {
Tracker = v;
}
}, 1);
var ReactiveVar;
module.watch(require("meteor/reactive-var"), {
ReactiveVar: function (v) {
ReactiveVar = v;
}
}, 2);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 3);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 4);
var SimpleSchema;
module.watch(require("meteor/aldeed:simple-schema"), {
SimpleSchema: function (v) {
SimpleSchema = v;
}
}, 5);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 6);
var cornerstone, cornerstoneTools;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
},
cornerstoneTools: function (v) {
cornerstoneTools = v;
}
}, 7);
OHIF.viewerbase.getImageDownloadDialogAnnotationTools = function () {
return ['length', 'probe', 'simpleAngle', 'arrowAnnotate', 'ellipticalRoi', 'rectangleRoi'];
};
Template.imageDownloadDialog.onCreated(function () {
var instance = Template.instance();
instance.schema = new SimpleSchema({
width: {
type: Number
},
height: {
type: Number
},
name: {
type: String,
defaultValue: 'image'
},
type: {
type: String,
allowedValues: ['jpeg', 'png'],
valuesLabels: ['JPEG', 'PNG'],
defaultValue: 'jpeg'
},
showAnnotations: {
type: Boolean,
label: 'Show Annotations',
defaultValue: true
}
});
instance.changeObserver = new Tracker.Dependency();
instance.keepAspect = new ReactiveVar(true);
instance.showAnnotations = new ReactiveVar(false);
instance.lastImage = {};
instance.getConfirmCallback = function () {
return function () {
instance.downloadImage();
};
};
});
Template.imageDownloadDialog.onRendered(function () {
var instance = Template.instance();
var viewportUtils = OHIF.viewerbase.viewportUtils;
instance.$viewportElement = instance.$('.viewport-element');
instance.viewportElement = instance.$viewportElement[0];
instance.$viewportPreview = instance.$('.viewport-preview');
instance.viewportPreview = instance.$viewportPreview[0];
cornerstone.enable(instance.viewportElement);
instance.downloadCanvas = $(instance.viewportElement).find('canvas')[0];
instance.form = instance.$('form').data('component');
instance.setElementSize = function (element, canvas, size, value) {
$(element)[size](value);
canvas[size] = value;
canvas.style[size] = value + "px";
instance.form.item(size).$element.val(value);
};
instance.toggleAnnotations = function (toggle) {
var action = toggle ? 'enable' : 'disable';
var annotationTools = OHIF.viewerbase.getImageDownloadDialogAnnotationTools();
annotationTools.forEach(function (tool) {
return cornerstoneTools[tool][action](instance.viewportElement);
});
};
instance.updateViewportPreview = function () {
instance.$viewportElement.one('cornerstoneimagerendered', function (event) {
// Wait for the tools to handle CornerstoneImageRendered event
Tracker.afterFlush(function () {
var enabledElement = cornerstone.getEnabledElement(event.currentTarget);
var formData = instance.form.value();
var image = instance.viewportPreview;
var type = 'image/' + formData.type;
var dataUrl = instance.downloadCanvas.toDataURL(type, 1);
image.src = dataUrl;
var $element = $(enabledElement.element);
var width = $element.width();
var height = $element.height();
if (width > 512 || height > 512) {
var multiplier = 512 / Math.max(width, height);
height *= multiplier;
width *= multiplier;
}
image.width = width;
image.height = height;
});
});
};
instance.downloadImage = function () {
var formData = instance.form.value();
var filename = formData.name + "." + formData.type;
var mimetype = "image/" + formData.type;
cornerstoneTools.saveAs(instance.viewportElement, filename, mimetype);
};
instance.autorun(function () {
instance.changeObserver.depend();
Session.get('UpdateDownloadViewport');
var activeViewport = viewportUtils.getActiveViewportElement();
if (activeViewport) {
var enabledElement = cornerstone.getEnabledElement(activeViewport);
var viewport = Object.assign({}, enabledElement.viewport);
delete viewport.scale;
viewport.translation = {
x: 0,
y: 0
};
cornerstone.loadImage(enabledElement.image.imageId).then(function (image) {
instance.lastImage = image;
var viewportElement = instance.viewportElement,
downloadCanvas = instance.downloadCanvas;
var formData = instance.form.value();
cornerstone.displayImage(viewportElement, image);
cornerstone.setViewport(viewportElement, viewport);
cornerstone.resize(viewportElement, true);
instance.toggleAnnotations(formData.showAnnotations);
var width = Math.min(formData.width || image.width, 16384);
var height = Math.min(formData.height || image.height, 16384);
instance.setElementSize(viewportElement, downloadCanvas, 'width', width);
instance.setElementSize(viewportElement, downloadCanvas, 'height', height);
cornerstone.fitToWindow(viewportElement);
instance.updateViewportPreview();
});
}
});
});
Template.imageDownloadDialog.onDestroyed(function () {
var instance = Template.instance();
cornerstone.disable(instance.viewportElement);
});
Template.imageDownloadDialog.events({
'click .js-keep-aspect': function (event, instance) {
var currentState = instance.keepAspect.get();
instance.keepAspect.set(!currentState);
instance.$('[data-key=width]').trigger('input');
},
'change [data-key=showAnnotations], change [data-key=type]': function (event, instance) {
instance.changeObserver.changed();
},
'input [data-key=width]': function (event, instance) {
var viewportElement = instance.viewportElement,
downloadCanvas = instance.downloadCanvas;
var formData = instance.form.value();
var _instance$lastImage = instance.lastImage,
width = _instance$lastImage.width,
height = _instance$lastImage.height;
var newWidth = formData.width;
instance.setElementSize(viewportElement, downloadCanvas, 'width', newWidth);
if (instance.keepAspect.get()) {
var multiplier = newWidth / width;
var newHeight = Math.round(height * multiplier);
instance.setElementSize(viewportElement, downloadCanvas, 'height', newHeight);
}
instance.changeObserver.changed();
},
'input [data-key=height]': function (event, instance) {
var viewportElement = instance.viewportElement,
downloadCanvas = instance.downloadCanvas;
var formData = instance.form.value();
var _instance$lastImage2 = instance.lastImage,
width = _instance$lastImage2.width,
height = _instance$lastImage2.height;
var newHeight = formData.height;
instance.setElementSize(viewportElement, downloadCanvas, 'height', newHeight);
if (instance.keepAspect.get()) {
var multiplier = newHeight / height;
var newWidth = Math.round(width * multiplier);
instance.setElementSize(viewportElement, downloadCanvas, 'width', newWidth);
}
instance.changeObserver.changed();
}
});
Template.imageDownloadDialog.helpers({
keepAspect: function () {
return Template.instance().keepAspect.get();
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"toolbarSectionButton":{"template.toolbarSectionButton.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/toolbarSectionButton/template.toolbarSectionButton.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("toolbarSectionButton");
Template["toolbarSectionButton"] = new Template("Template.toolbarSectionButton", (function() {
var view = this;
return Blaze.If(function() {
return Spacebars.call(Spacebars.dot(view.lookup("."), "buttonTemplateName"));
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return {
template: Spacebars.call(Spacebars.dot(view.lookup("."), "buttonTemplateName")),
data: Spacebars.call(view.lookup("."))
};
}, function() {
return Spacebars.include(function() {
return Spacebars.call(Template.__dynamic);
});
}), "\n " ];
}, function() {
return [ "\n ", HTML.DIV({
id: function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("."), "id"));
},
tabindex: "1",
class: function() {
return [ "toolbarSectionButton rp-x-1 ", Spacebars.mustache(Spacebars.dot(view.lookup("."), "classes")), " ", Spacebars.mustache(view.lookup("activeClass")), " ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("or"), Spacebars.dot(view.lookup("."), "disabled"), Spacebars.dataMustache(view.lookup("disableButton")));
}, function() {
return "disabled";
}), " ", Blaze.If(function() {
return Spacebars.call(view.lookup("hasSubTools"));
}, function() {
return "expandable";
}) ];
},
title: function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("."), "tooltipTitle"));
}
}, "\n ", HTML.DIV({
class: "svgContainer"
}, "\n ", Blaze.Let({
svg: function() {
return Spacebars.call(view.lookup("svgLink"));
},
icon: function() {
return Spacebars.call(view.lookup("iconClasses"));
}
}, function() {
return [ "\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("svg"));
}, function() {
return [ "\n ", HTML.SVG("\n ", HTML.USE({
"xlink:href": function() {
return Spacebars.mustache(view.lookup("absoluteUrl"), view.lookup("svg"));
}
}), "\n "), "\n " ];
}, function() {
return [ "\n ", HTML.I({
class: function() {
return Spacebars.mustache(view.lookup("icon"));
}
}), "\n " ];
}), "\n " ];
}), "\n "), "\n ", HTML.DIV({
class: "buttonLabel"
}, "\n ", HTML.SPAN(Blaze.View("lookup:..title", function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("."), "title"));
})), "\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("hasSubTools"));
}, function() {
return [ "\n ", HTML.I({
class: "fa fa-caret-down expanded-status",
"aria-hidden": "true"
}), "\n " ];
}), "\n "), "\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("hasSubTools"));
}, function() {
return [ "\n ", HTML.DIV({
class: "toolbarSectionDrawerContainer"
}, "\n ", HTML.DIV({
class: "toolbarSectionDrawer"
}, "\n ", Blaze.If(function() {
return Spacebars.call(Spacebars.dot(view.lookup("."), "subToolsTemplateName"));
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return {
template: Spacebars.call(Spacebars.dot(view.lookup("."), "subToolsTemplateName")),
data: Spacebars.call(view.lookup("."))
};
}, function() {
return Spacebars.include(function() {
return Spacebars.call(Template.__dynamic);
});
}), "\n " ];
}, function() {
return [ "\n ", Blaze.If(function() {
return Spacebars.call(Spacebars.dot(view.lookup("."), "subTools"));
}, function() {
return [ "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(Spacebars.dot(view.lookup("."), "subTools")),
_variable: "subTool"
};
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return Spacebars.call(view.lookup("subTool"));
}, function() {
return Spacebars.include(view.lookupTemplate("toolbarSectionButton"));
}), "\n " ];
}), "\n " ];
}), "\n " ];
}), "\n "), "\n "), " \n " ];
}), "\n "), "\n " ];
});
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"toolbarSectionButton.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/toolbarSectionButton/toolbarSectionButton.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 1);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 2);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 3);
Template.toolbarSectionButton.onCreated(function () {
var instance = Template.instance();
instance.isActive = function (activeToolId) {
OHIF.commands.last.dep.depend();
var subTools = instance.data.subTools;
var currentId = instance.data.id;
var isCurrentTool = currentId === activeToolId;
var isSubTool = subTools && _.findWhere(subTools, {
id: activeToolId
});
var activeCommandButtons = Session.get('ToolManagerActiveCommandButtons') || [];
var isActiveCommandButton = activeCommandButtons.indexOf(instance.data.id) !== -1;
var isActive = typeof instance.data.active === 'function' && instance.data.active(); // Check if the current tool, a sub tool or a command button is active
return isActive || isCurrentTool || isSubTool || isActiveCommandButton;
};
instance.getActiveToolSubProperty = function (propertyName, activeToolId) {
var instance = Template.instance();
var subTools = instance.data.subTools;
var defaultProperty = instance.data[propertyName];
var currentId = instance.data.id;
if (subTools && activeToolId !== currentId && instance.isActive(activeToolId)) {
var subTool = _.findWhere(subTools, {
id: activeToolId
});
return subTool ? subTool[propertyName] : defaultProperty;
} else {
return defaultProperty;
}
};
instance.autorun(function (computation) {
Session.get('ToolManagerActiveToolUpdated'); // Get the last executed command
var lastCommand = OHIF.commands.last.get(); // Prevent running this computation on its first run
if (computation.firstRun) return; // Stop here if it's not the last command or if it's already an active tool
var id = instance.data.id;
var activeToolId = OHIF.viewerbase.toolManager.getActiveTool();
if (lastCommand !== id || instance.isActive(activeToolId)) return; // Add an active class to a button for 100ms to give the impression the button was pressed
var flashButton = function ($element) {
$element.addClass('active');
setTimeout(function () {
if ($element.hasClass('expandable') && $element.find('.toolbarSectionButton.active').length) return;
var activeToolId = OHIF.viewerbase.toolManager.getActiveTool();
var isActive = instance.isActive(activeToolId);
if (!isActive) {
$element.removeClass('active');
}
}, 100);
}; // Flash the active button
var $button = instance.$('.toolbarSectionButton').first();
flashButton($button); // Flash the parent button as well in case of this button is inside a drawer
var $parentButton = $button.closest('.toolbarSectionButton.expandable');
if ($parentButton.length) {
flashButton($parentButton);
}
});
});
Template.toolbarSectionButton.helpers({
activeClass: function () {
Session.get('ToolManagerActiveToolUpdated');
var instance = Template.instance();
var activeToolId = OHIF.viewerbase.toolManager.getActiveTool();
var isActive = instance.isActive(activeToolId);
return isActive ? 'active' : '';
},
svgLink: function () {
Session.get('ToolManagerActiveToolUpdated');
var instance = Template.instance();
var activeToolId = OHIF.viewerbase.toolManager.getActiveTool();
var svgLink = instance.getActiveToolSubProperty('svgLink', activeToolId);
return _.isFunction(svgLink) ? svgLink() : svgLink;
},
iconClasses: function () {
Session.get('ToolManagerActiveToolUpdated');
var instance = Template.instance();
var activeToolId = OHIF.viewerbase.toolManager.getActiveTool();
var iconClasses = instance.getActiveToolSubProperty('iconClasses', activeToolId);
return _.isFunction(iconClasses) ? iconClasses() : iconClasses;
},
disableButton: function () {
Session.get('activeViewport');
Session.get('LayoutManagerUpdated');
var instance = Template.instance();
var isCommandDisabled = OHIF.commands.isDisabled(instance.data.id);
var isFunctionDisabled = instance.data.disableFunction && instance.data.disableFunction();
return isCommandDisabled || isFunctionDisabled;
},
hasSubTools: function () {
return this.subTools || this.subToolsTemplateName;
}
});
Template.toolbarSectionButton.events({
'click .toolbarSectionButton:not(.expandable)': function (event, instance) {
// Prevent the event from bubbling to parent tools
event.stopPropagation();
var $currentTarget = $(event.currentTarget); // Stop here if the button is disabled or customAction
if ($currentTarget.hasClass('disabled') || $currentTarget.hasClass('customAction')) {
return;
} // Run the command attached to the button
OHIF.commands.run(instance.data.id);
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"toolbarSectionTools":{"template.toolbarSectionTools.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/toolbarSectionTools/template.toolbarSectionTools.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("toolbarSectionTools");
Template["toolbarSectionTools"] = new Template("Template.toolbarSectionTools", (function() {
var view = this;
return HTML.DIV({
class: "toolbarSectionTools pull-left m-t-1 rm-l-3"
}, "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(view.lookup("toolbarButtons")),
_variable: "toolbarButton"
};
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return Spacebars.call(view.lookup("toolbarButton"));
}, function() {
return Spacebars.include(view.lookupTemplate("toolbarSectionButton"));
}), "\n " ];
}), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"toolbarSectionTools.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/toolbarSectionTools/toolbarSectionTools.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 1);
Template.toolbarSectionTools.events({
'click .expandable': function (event, instance) {
var $target = $(event.currentTarget);
var isExpanded = $target.hasClass('expanded');
$target.toggleClass('expanded', !isExpanded); // Remove the previously set repositioning css attribute
var $box = $target.find('.toolbarSectionDrawerContainer:first');
$box.css('left', ''); // Stop here if the tool group is not expanded
if (isExpanded) {
return;
} // Move the box left or right if it is overflowing the window
var transitionendHandler = function (event) {
var originalEvent = event.originalEvent;
var propertyName = originalEvent && originalEvent.propertyName;
if (propertyName && propertyName === 'transform') {
$target.off('transitionend', transitionendHandler);
} else {
return;
}
var boxWidth = $box.outerWidth();
var start = $box.offset().left;
var bodyWidth = $(document.body).outerWidth();
var end = start + boxWidth;
if (start < 0) {
$box.css('left', "calc(50% - " + start + "px)");
} else if (end > bodyWidth) {
var diff = end - bodyWidth;
$box.css('left', "calc(50% - " + diff + "px)");
}
}; // Attach the handler to deal with position fixing
$target.on('transitionend', transitionendHandler);
},
'focusout .expandable': function (event, instance) {
var target = event.target;
var currentTarget = event.currentTarget; // Postpone the execution to be able to get the focused element
Meteor.defer(function () {
var $focused = $(':focus');
var $expandable = $(currentTarget).closest('.expandable');
var focusInside = $expandable.find(':focus').length; // Check if the expandable lost the focus
if (!$focused.length || !focusInside) {
// Stop here if focus is going from subtool to expandable tool
if (currentTarget !== target && $focused[0] === currentTarget) {
return;
}
$expandable.removeClass('expanded');
}
});
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"userPreferences":{"template.dialog.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/userPreferences/template.dialog.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("userPreferencesDialog");
Template["userPreferencesDialog"] = new Template("Template.userPreferencesDialog", (function() {
var view = this;
return Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("extend"), view.lookup("."), Spacebars.kw({
class: "themed",
dialogClass: "dialog-user-preferences modal-lg",
title: "User Preferences"
}));
}, function() {
return Spacebars.include(view.lookupTemplate("dialogSimple"), function() {
return [ "\n ", HTML.DIV({
class: "dialog-separator-after"
}, "\n ", HTML.UL({
class: "nav nav-tabs"
}, "\n ", HTML.LI({
role: "presentation",
class: function() {
return Spacebars.mustache(view.lookup("tabClasses"), "hotkeys");
}
}, "\n ", HTML.A({
href: "#",
"data-id": "hotkeys"
}, "Keyboard Shortcuts"), "\n "), "\n ", HTML.LI({
role: "presentation",
class: function() {
return Spacebars.mustache(view.lookup("tabClasses"), "wwwc");
}
}, "\n ", HTML.A({
href: "#",
"data-id": "wwwc"
}, "Window/Levels"), "\n "), "\n "), "\n "), "\n ", HTML.DIV({
class: function() {
return Blaze.Unless(function() {
return Spacebars.dataMustache(view.lookup("eq"), Spacebars.dot(view.lookup("instance"), "activeTab", "get"), "hotkeys");
}, function() {
return "hidden";
});
}
}, "\n ", Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("extend"), Spacebars.kw({
contextName: "viewer"
}));
}, function() {
return Spacebars.include(view.lookupTemplate("hotkeysForm"));
}), "\n "), "\n ", HTML.DIV({
class: function() {
return Blaze.Unless(function() {
return Spacebars.dataMustache(view.lookup("eq"), Spacebars.dot(view.lookup("instance"), "activeTab", "get"), "wwwc");
}, function() {
return "hidden";
});
}
}, "\n ", Spacebars.include(view.lookupTemplate("windowLevelPresetsForm")), "\n "), "\n " ];
});
});
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"dialog.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/userPreferences/dialog.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var ReactiveVar;
module.watch(require("meteor/reactive-var"), {
ReactiveVar: function (v) {
ReactiveVar = v;
}
}, 1);
Template.userPreferencesDialog.onCreated(function () {
var instance = Template.instance();
instance.activeTab = new ReactiveVar('hotkeys');
});
Template.userPreferencesDialog.events({
'click .nav-tabs li a': function (event, instance) {
var tabId = $(event.currentTarget).attr('data-id');
instance.activeTab.set(tabId);
}
});
Template.userPreferencesDialog.helpers({
tabClasses: function (tabId) {
var instance = Template.instance();
var activeTab = instance.activeTab.get();
return tabId === activeTab ? 'active' : '';
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"confirmDeleteDialog":{"template.confirmDeleteDialog.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/confirmDeleteDialog/template.confirmDeleteDialog.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("confirmDeleteDialog");
Template["confirmDeleteDialog"] = new Template("Template.confirmDeleteDialog", (function() {
var view = this;
return HTML.DIV({
id: "confirmDeleteDialog",
class: "dialog-animated",
tabindex: "0"
}, "\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("title"));
}, function() {
return [ "\n ", HTML.H5(Blaze.View("lookup:title", function() {
return Spacebars.mustache(view.lookup("title"));
})), "\n " ];
}, function() {
return [ "\n ", HTML.H5("Remove data from Timepoint?"), "\n " ];
}), "\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("text"));
}, function() {
return [ "\n ", HTML.P(Blaze.View("lookup:text", function() {
return Spacebars.mustache(view.lookup("text"));
})), "\n " ];
}, function() {
return [ "\n ", HTML.P("Are you sure you would like to remove the measurement data at this timepoint?"), "\n " ];
}), HTML.Raw('\n <button id="cancel" class="btn btn-link" tabindex="1">Cancel</button>\n <button id="confirm" class="btn btn-primary" tabindex="0">OK</button>\n '));
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"confirmDeleteDialog.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/confirmDeleteDialog/confirmDeleteDialog.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var dialogUtils;
module.watch(require("../../../lib/dialogUtils"), {
dialogUtils: function (v) {
dialogUtils = v;
}
}, 1);
// Global object of key names (TODO: put this somewhere else)
var keys = {
ESC: 27,
ENTER: 13
};
Template.confirmDeleteDialog.events({
'click #cancel, click #close': function () {
// Action canceled, just close dialog without calling callback
dialogUtils.closeHandler(false);
},
'click #confirm': function () {
// Action confirmed, close dialog and calls callback, if exists
dialogUtils.closeHandler();
},
'keydown #confirmDeleteDialog': function (e) {
// Action canceled, just close dialog without calling callback
if (e.which === keys.ESC) {
dialogUtils.closeHandler(false);
return false;
}
if (this.keyPressAllowed === false) {
return;
} // If Enter is pressed
if (e.which === keys.ENTER) {
// Action confirmed, close dialog and calls callback, if exists
dialogUtils.closeHandler();
}
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"textMarkerDialogs":{"template.textMarkerDialogs.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/textMarkerDialogs/template.textMarkerDialogs.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("textMarkerDialogs");
Template["textMarkerDialogs"] = new Template("Template.textMarkerDialogs", (function() {
var view = this;
return [ HTML.getTag("dialog")({
id: "textMarkerOptionsDialog",
oncontextmenu: "return false",
class: "textMarkerDialog noselect"
}, "\n ", HTML.H5("Spine Labels"), "\n ", HTML.A({
class: "closeTextMarkerDialogs"
}, Spacebars.include(view.lookupTemplate("iconCrossCircle"))), "\n ", HTML.DIV({
class: "optionsDiv"
}, "\n ", HTML.DIV({
class: "select2-wrapper optionBox"
}, "\n ", HTML.LABEL({
for: "startFrom"
}, "Label: "), "\n ", HTML.SELECT({
name: "start",
id: "startFrom",
tabindex: "-1",
class: "select2"
}, "\n ", HTML.Comment(" Cervical spine !"), "\n ", HTML.OPTION({
value: "C1",
selected: ""
}, "C1"), "\n ", HTML.OPTION({
value: "C2"
}, "C2"), "\n ", HTML.OPTION({
value: "C3"
}, "C3"), "\n ", HTML.OPTION({
value: "C4"
}, "C4"), "\n ", HTML.OPTION({
value: "C5"
}, "C5"), "\n ", HTML.OPTION({
value: "C6"
}, "C6"), "\n ", HTML.OPTION({
value: "C7"
}, "C7"), "\n\n ", HTML.Comment(" Thoracic spine !"), "\n ", HTML.OPTION({
value: "T1"
}, "T1"), "\n ", HTML.OPTION({
value: "T2"
}, "T2"), "\n ", HTML.OPTION({
value: "T3"
}, "T3"), "\n ", HTML.OPTION({
value: "T4"
}, "T4"), "\n ", HTML.OPTION({
value: "T5"
}, "T5"), "\n ", HTML.OPTION({
value: "T6"
}, "T6"), "\n ", HTML.OPTION({
value: "T7"
}, "T7"), "\n ", HTML.OPTION({
value: "T8"
}, "T8"), "\n ", HTML.OPTION({
value: "T9"
}, "T9"), "\n ", HTML.OPTION({
value: "T10"
}, "T10"), "\n ", HTML.OPTION({
value: "T11"
}, "T11"), "\n ", HTML.OPTION({
value: "T12"
}, "T12"), "\n\n ", HTML.Comment(" Lumbar spine !"), "\n ", HTML.OPTION({
value: "L1"
}, "L1"), "\n ", HTML.OPTION({
value: "L2"
}, "L2"), "\n ", HTML.OPTION({
value: "L3"
}, "L3"), "\n ", HTML.OPTION({
value: "L4"
}, "L4"), "\n ", HTML.OPTION({
value: "L5"
}, "L5"), "\n "), "\n "), "\n ", HTML.DIV({
class: "optionBox"
}, "\n ", HTML.DIV({
class: "btn-group iconSwitch",
"data-toggle": "buttons"
}, "\n ", HTML.LABEL({
for: "ascending",
class: "btn btn-link",
title: "Add labels from head to feet (down) or feet to head (up)",
"data-toggle": "tooltip",
"data-container": "body"
}, "\n ", HTML.INPUT({
type: "checkbox",
id: "ascending"
}), " ", HTML.SPAN({
class: "on"
}, HTML.I({
class: "fa fa-long-arrow-up",
"aria-hidden": "true"
})), " ", HTML.SPAN({
class: "off"
}, HTML.I({
class: "fa fa-long-arrow-down",
"aria-hidden": "true"
})), "\n "), "\n "), "\n "), "\n ", HTML.BUTTON({
id: "clearLabels",
class: "btn viewerBtn btn-xs",
type: "button"
}, "\n Clear Labels ", HTML.I({
class: "viewerIcon-clear"
}), "\n "), "\n "), " \n "), "\n\n ", HTML.getTag("dialog")({
id: "textMarkerRelabelDialog",
oncontextmenu: "return false",
class: "textMarkerDialog noselect"
}, "\n ", HTML.H5("Change Spine Label"), "\n ", HTML.DIV({
class: "relabelOptions"
}, "\n\n ", HTML.DIV({
class: "select2-wrapper optionBox"
}, "\n ", HTML.LABEL({
for: "relabelSelect"
}, "Label:"), "\n ", HTML.SELECT({
name: "relabelSelect",
class: "relabelSelect"
}, "\n ", HTML.Comment(" Cervical spine !"), "\n ", HTML.OPTION({
value: "C1"
}, "C1"), "\n ", HTML.OPTION({
value: "C2"
}, "C2"), "\n ", HTML.OPTION({
value: "C3"
}, "C3"), "\n ", HTML.OPTION({
value: "C4"
}, "C4"), "\n ", HTML.OPTION({
value: "C5"
}, "C5"), "\n ", HTML.OPTION({
value: "C6"
}, "C6"), "\n ", HTML.OPTION({
value: "C7"
}, "C7"), "\n\n ", HTML.Comment(" Thoracic spine !"), "\n ", HTML.OPTION({
value: "T1"
}, "T1"), "\n ", HTML.OPTION({
value: "T2"
}, "T2"), "\n ", HTML.OPTION({
value: "T3"
}, "T3"), "\n ", HTML.OPTION({
value: "T4"
}, "T4"), "\n ", HTML.OPTION({
value: "T5"
}, "T5"), "\n ", HTML.OPTION({
value: "T6"
}, "T6"), "\n ", HTML.OPTION({
value: "T7"
}, "T7"), "\n ", HTML.OPTION({
value: "T8"
}, "T8"), "\n ", HTML.OPTION({
value: "T9"
}, "T9"), "\n ", HTML.OPTION({
value: "T10"
}, "T10"), "\n ", HTML.OPTION({
value: "T11"
}, "T11"), "\n ", HTML.OPTION({
value: "T12"
}, "T12"), "\n\n ", HTML.Comment(" Lumbar spine !"), "\n ", HTML.OPTION({
value: "L1"
}, "L1"), "\n ", HTML.OPTION({
value: "L2"
}, "L2"), "\n ", HTML.OPTION({
value: "L3"
}, "L3"), "\n ", HTML.OPTION({
value: "L4"
}, "L4"), "\n ", HTML.OPTION({
value: "L5"
}, "L5"), "\n "), "\n "), "\n "), "\n ", HTML.DIV({
class: "relabelButtons"
}, "\n ", HTML.BUTTON({
class: "relabelRemove btn btn-xs btn-secondary viewerBtn"
}, "Delete"), "\n ", HTML.BUTTON({
class: "relabelConfirm btn btn-xs viewerBtn"
}, "Save"), "\n "), "\n ", HTML.DIV({
class: "dialog arrow"
}, "\n "), "\n ") ];
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"textMarkerDialogs.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/textMarkerDialogs/textMarkerDialogs.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 1);
var toolManager;
module.watch(require("../../../lib/toolManager"), {
toolManager: function (v) {
toolManager = v;
}
}, 2);
var viewportUtils;
module.watch(require("../../../lib/viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 3);
Template.textMarkerDialogs.events({
'change #startFrom': function (e) {
var config = cornerstoneTools.textMarker.getConfiguration();
config.current = $(e.target).val(); //console.log("Changed starting point to: " + config.current);
},
'change #ascending': function (e) {
var config = cornerstoneTools.textMarker.getConfiguration();
config.ascending = $(e.target).is(':checked');
var currentIndex = config.markers.indexOf(config.current);
config.current = config.markers[currentIndex];
var nextMarker = config.current;
$('#startFrom').val(nextMarker).trigger('change'); //console.log("Changed ascending to: " + config.ascending);
},
'click #clearLabels': function () {
var element = viewportUtils.getActiveViewportElement();
var toolType = 'textMarker';
var toolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager;
var toolState = toolStateManager.toolState; // We might want to make this a convenience function in cornerstoneTools
var stack = cornerstoneTools.getToolState(element, 'stack');
if (stack && stack.data.length && stack.data[0].imageIds.length) {
var imageIds = stack.data[0].imageIds; // Clear the tool data for each image in the stack
imageIds.forEach(function (imageId) {
if (toolState.hasOwnProperty(imageId)) {
var toolData = toolState[imageId];
if (toolData.hasOwnProperty(toolType)) {
delete toolData[toolType];
}
}
});
}
cornerstone.updateImage(element);
},
'click .closeTextMarkerDialogs': function () {
var defaultTool = toolManager.getDefaultTool();
toolManager.setActiveTool(defaultTool);
document.getElementById('textMarkerOptionsDialog').close();
$('#spine').removeClass('active');
$('#' + defaultTool).addClass('active');
}
});
Template.textMarkerDialogs.onRendered(function () {
var optionsDialog = $('#textMarkerOptionsDialog');
optionsDialog.draggable();
dialogPolyfill.registerDialog(optionsDialog.get(0));
var relabelDialog = $('#textMarkerRelabelDialog');
relabelDialog.draggable();
dialogPolyfill.registerDialog(relabelDialog.get(0));
$(document).on('click', function (event) {
if (!$(event.target).closest('.select2-wrapper').length) {
setTimeout(function () {
$('#startFrom, .relabelSelect').select2('close');
}, 200);
}
});
$(document).on('touchmove', function (event) {
if (!$(event.target).closest('.select2-container').length) {
setTimeout(function () {
$('#startFrom, .relabelSelect').select2('close');
}, 200);
}
});
$(function () {
FastClick.attach(document.body);
var $customSelects = $('#startFrom, .relabelSelect');
$customSelects.select2({
/**
* Adds needsclick class to all DOM elements in the Select2 results list
* so they can be accessible on iOS mobile when FastClick is initiated too.
*/
templateResult: function (result, container) {
if (!result.id) {
return result.text;
}
container.className += ' needsclick';
return result.text;
},
placeholder: 'C1',
minimumResultsForSearch: -1,
theme: 'viewerDropdown'
});
/**
* Additional to tweaking the templateResult option in Select2,
* add needsclick class to all DOM elements in the Select2 container,
* so they can be accessible on iOS mobile when FastClick is initiated too.
*
* More info about needsclick:
* https://github.com/ftlabs/fastclick#ignore-certain-elements-with-needsclick
*
*/
$customSelects.each(function (index, el) {
$(el).data('select2').$container.find('*').addClass('needsclick');
});
});
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"seriesQuickSwitch":{"template.seriesQuickSwitch.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/seriesQuickSwitch/template.seriesQuickSwitch.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("seriesQuickSwitch");
Template["seriesQuickSwitch"] = new Template("Template.seriesQuickSwitch", (function() {
var view = this;
return Blaze.If(function() {
return Spacebars.call(view.lookup("shallDisplay"));
}, function() {
return [ "\n ", HTML.DIV({
class: function() {
return [ "series-quick-switch ", Spacebars.mustache(view.lookup("side")), " clearfix noselect" ];
}
}, "\n ", HTML.DIV({
class: "series-switch rp-t-1 rp-x-1"
}, "\n ", HTML.DIV({
class: "title-label"
}, "Series"), "\n ", HTML.DIV({
class: "series-box r-font"
}, "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(view.lookup("seriesItems")),
_variable: "seriesItem"
};
}, function() {
return [ "\n ", HTML.DIV({
class: function() {
return [ "series-item ", Spacebars.mustache(Spacebars.dot(view.lookup("seriesItem"), "class")) ];
}
}, Blaze.View("lookup:seriesItem.value", function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("seriesItem"), "value"));
})), "\n " ];
}), "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("series-browser"),
scrollStep: Spacebars.call(201)
};
}, function() {
return Spacebars.include(view.lookupTemplate("scrollArea"), function() {
return [ "\n ", HTML.DIV({
class: "clearfix thumbnails-wrapper"
}, "\n ", Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({
studyMetadata: Spacebars.dot(view.lookup("instance"), "currentStudy")
}));
}, function() {
return Spacebars.include(view.lookupTemplate("studyBrowserSeries"));
}), "\n "), "\n " ];
});
}), "\n "), "\n "), "\n ", HTML.DIV({
class: "study-switch rp-t-1 rp-x-1"
}, "\n ", HTML.DIV({
class: "title-label"
}, "Study"), "\n ", HTML.DIV({
class: "study-box r-font"
}, "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("study-browser"),
scrollStep: Spacebars.call(91)
};
}, function() {
return Spacebars.include(view.lookupTemplate("scrollArea"), function() {
return [ "\n ", Blaze._TemplateWith(function() {
return {
template: Spacebars.call(view.lookup("studyBrowserTemplate")),
data: Spacebars.call(Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({
currentStudy: Spacebars.dot(view.lookup("instance"), "currentStudy")
})))
};
}, function() {
return Spacebars.include(function() {
return Spacebars.call(Template.__dynamic);
});
}), "\n " ];
});
}), "\n "), "\n "), "\n "), "\n " ];
});
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"seriesQuickSwitch.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var ReactiveVar;
module.watch(require("meteor/reactive-var"), {
ReactiveVar: function (v) {
ReactiveVar = v;
}
}, 1);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 2);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 3);
Template.seriesQuickSwitch.onCreated(function () {
var instance = Template.instance(); // Defines the study being shown in the current viewport
instance.currentStudy = new ReactiveVar(); // Gets the viewport data for the given viewport index
instance.getViewportData = function (viewportIndex) {
var layoutManager = OHIF.viewerbase.layoutManager;
return layoutManager && layoutManager.viewportData && layoutManager.viewportData[viewportIndex];
}; // Gets the current viewport data
var viewportIndex = instance.data.viewportIndex;
instance.study = {};
instance.lastStudy = {};
instance.autorun(function () {
OHIF.viewerbase.layoutManager.observer.depend();
var viewportData = instance.getViewportData(viewportIndex); // @TypeSafeStudies
if (viewportData) {
// Finds the current study and return it
instance.study = OHIF.viewer.Studies.findBy({
studyInstanceUid: viewportData.studyInstanceUid
});
}
if (!instance.study) {
instance.study = OHIF.viewer.Studies.getElementByIndex(0);
}
if (!instance.study) {
return;
}
if (instance.study.studyInstanceUid !== instance.lastStudy.studyInstanceUid) {
// Change the current study to update the thumbnails
instance.currentStudy.set(instance.study);
instance.lastStudy = instance.study;
}
});
});
Template.seriesQuickSwitch.helpers({
shallDisplay: function () {
var instance = Template.instance();
var _instance$data = instance.data,
rows = _instance$data.rows,
columns = _instance$data.columns;
return OHIF.viewer.displaySeriesQuickSwitch && rows === 1 && columns <= 2;
},
side: function () {
var instance = Template.instance();
var _instance$data2 = instance.data,
columns = _instance$data2.columns,
viewportIndex = _instance$data2.viewportIndex;
if (columns === 1) return '';
return viewportIndex === 0 ? 'left' : 'right';
},
seriesItems: function () {
var instance = Template.instance();
OHIF.viewerbase.layoutManager.observer.depend();
var viewportIndex = instance.data.viewportIndex;
var viewportData = OHIF.viewerbase.layoutManager.viewportData[viewportIndex];
var study = instance.currentStudy.get();
var seriesItems = [];
var displaySets = study.displaySets;
if (!displaySets.length) {
displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(study);
study.displaySets = displaySets;
study.setDisplaySets(displaySets);
study.forEachDisplaySet(function (displaySet) {
OHIF.viewerbase.stackManager.makeAndAddStack(study, displaySet);
});
}
var items = displaySets.length;
for (var i = 0; i < items; i++) {
var displaySet = displaySets[i];
var item = {
"class": ''
};
seriesItems.push(item);
if (i === 8 && items !== 9) {
item.class += ' count';
item.value = items;
break;
}
if (displaySet.displaySetInstanceUid === viewportData.displaySetInstanceUid) {
item.class += ' active';
}
}
return seriesItems;
},
studyBrowserTemplate: function () {
return OHIF.viewer.quickSwitchStudyBrowserTemplate || 'studyBrowserQuickSwitch';
}
});
Template.seriesQuickSwitch.events({
'mouseenter .series-switch, rescale .series-switch': function (event, instance) {
// Control the width of the series browser
var $switch = $(event.currentTarget);
var $seriesBrowser = $switch.find('.series-browser');
var $seriesQuickSwitch = $switch.closest('.series-quick-switch');
var isRight = $seriesQuickSwitch.hasClass('right');
var switchOffsetLeft = $switch.offset().left;
var switchOuterWidth = $switch.outerWidth();
var browserWidth;
if (isRight) {
browserWidth = $(window).width() - switchOffsetLeft;
} else {
browserWidth = switchOffsetLeft + switchOuterWidth;
}
$seriesBrowser.width(browserWidth - browserWidth % 240);
var $quickSwitch = instance.$('.series-quick-switch');
if ($quickSwitch.is(':hover')) {
$quickSwitch.addClass('series-triggered');
}
},
'mouseleave .series-browser': function (event, instance) {
$(event.currentTarget).children('.scrollable').stop().animate({
scrollTop: 0
}, 300, 'swing');
},
'mouseleave .series-quick-switch': function (event, instance) {
$(event.currentTarget).removeClass('series-triggered');
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"studySeriesQuickSwitch":{"template.studySeriesQuickSwitch.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/studySeriesQuickSwitch/template.studySeriesQuickSwitch.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("studySeriesQuickSwitch");
Template["studySeriesQuickSwitch"] = new Template("Template.studySeriesQuickSwitch", (function() {
var view = this;
return HTML.DIV({
class: function() {
return [ "quickSwitchWrapper ", Spacebars.mustache(view.lookup("side")) ];
}
}, "\n ", HTML.DIV({
class: function() {
return [ "quickSwitch js-quick-switch clearfix ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("eq"), view.lookup("side"), "right");
}, function() {
return "rp-l-3";
}), Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("eq"), view.lookup("side"), "left");
}, function() {
return "rp-r-3";
}) ];
}
}, "\n ", HTML.DIV({
class: function() {
return [ "switchSection switchSectionStudy rp-t-1 rp-x-1 ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("eq"), view.lookup("side"), "right");
}, function() {
return "pull-left";
}, function() {
return "pull-right";
}) ];
}
}, "\n ", HTML.Raw('<div class="label">Study</div>'), "\n ", HTML.DIV({
class: "studySwitch"
}, "\n ", HTML.Raw('<div class="studyBox"></div>'), "\n ", HTML.DIV({
class: "switchHover studyHover clearfix"
}, "\n ", HTML.DIV({
class: function() {
return [ "scrollArea ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("isMac"));
}, function() {
return "is-mac";
}) ];
}
}, "\n ", Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({
timepointViewType: "key"
}));
}, function() {
return Spacebars.include(view.lookupTemplate("studyTimepointBrowser"));
}), "\n "), "\n "), "\n "), "\n "), "\n ", HTML.DIV({
class: function() {
return [ "switchSection switchSectionSeries rp-t-1 rp-x-1 ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("eq"), view.lookup("side"), "right");
}, function() {
return "pull-left";
}, function() {
return "pull-right";
}) ];
}
}, "\n ", Blaze.Let({
thumbnailsList: function() {
return Spacebars.call(Spacebars.dataMustache(view.lookup("studyThumbnails"), view.lookup("currentStudy")));
}
}, function() {
return [ "\n ", HTML.DIV({
class: "label"
}, "Series"), "\n ", HTML.DIV({
class: "seriesSwitch clearfix"
}, "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(view.lookup("thumbnailsList")),
_variable: "thumbnail"
};
}, function() {
return [ "\n ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("lt"), view.lookup("@index"), 8);
}, function() {
return [ "\n ", HTML.DIV({
class: function() {
return [ "seriesItem ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("eq"), view.lookup("side"), "right");
}, function() {
return "pull-left";
}, function() {
return "pull-right";
}), " ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("isDisplaySetActive"), Spacebars.dot(view.lookup("thumbnail"), "stack", "displaySetInstanceUid"), view.lookup("viewportIndex"));
}, function() {
return "active";
}) ];
}
}), "\n " ];
}, function() {
return [ "\n ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("eq"), view.lookup("@index"), 8);
}, function() {
return [ "\n ", HTML.DIV({
class: function() {
return [ "seriesItem count ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("eq"), view.lookup("side"), "right");
}, function() {
return "pull-left";
}, function() {
return "pull-right";
}) ];
}
}, Blaze.View("lookup:thumbnailsList.length", function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("thumbnailsList"), "length"));
})), "\n " ];
}), "\n " ];
}), "\n " ];
}), "\n ", HTML.DIV({
class: "switchHover seriesHover clearfix"
}, "\n ", HTML.DIV({
class: function() {
return [ "scrollArea ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("isMac"));
}, function() {
return "is-mac";
}) ];
}
}, "\n ", HTML.DIV({
class: "thumbnailsWrapper"
}, "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(view.lookup("thumbnailsList")),
_variable: "thumbnail"
};
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({
thumbnail: view.lookup("thumbnail")
}));
}, function() {
return Spacebars.include(view.lookupTemplate("thumbnailEntry"));
}), "\n " ];
}), "\n "), "\n "), "\n "), "\n "), "\n " ];
}), "\n "), "\n "), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"studySeriesQuickSwitch.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/studySeriesQuickSwitch/studySeriesQuickSwitch.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var ReactiveVar;
module.watch(require("meteor/reactive-var"), {
ReactiveVar: function (v) {
ReactiveVar = v;
}
}, 1);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 2);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 3);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 4);
Template.studySeriesQuickSwitch.onCreated(function () {
var instance = Template.instance(); // Defines the study being shown in the current viewport
instance.data.currentStudy = new ReactiveVar(); // Gets the viewport data for the given viewport index
instance.getViewportData = function (viewportIndex) {
var layoutManager = OHIF.viewerbase.layoutManager;
return layoutManager && layoutManager.viewportData && layoutManager.viewportData[viewportIndex];
}; // Gets the current viewport data
var viewportIndex = instance.data.viewportIndex;
instance.study = {};
instance.lastStudy = {};
instance.autorun(function () {
Session.get('LayoutManagerUpdated');
var viewportData = instance.getViewportData(viewportIndex); // @TypeSafeStudies
if (viewportData) {
// Finds the current study and return it
instance.study = OHIF.viewer.Studies.findBy({
studyInstanceUid: viewportData.studyInstanceUid
});
} else {
instance.study = OHIF.viewer.Studies.getElementByIndex(0);
}
if (!instance.study) {
return;
}
if (instance.study.studyInstanceUid !== instance.lastStudy.studyInstanceUid) {
// Change the current study to update the thumbnails
instance.data.currentStudy.set(instance.study);
instance.lastStudy = instance.study;
}
});
});
var checkScrollArea = function (element) {
var scrollHeight = element.scrollHeight,
offsetHeight = element.offsetHeight,
scrollTop = element.scrollTop;
var matrix = $(element).find('.thumbnailsWrapper').css('transform');
var translateY = 0;
if (matrix && matrix !== 'none') {
translateY = parseInt(matrix.match(/-?[\d\.]+/g)[5]);
}
if (scrollHeight > offsetHeight + scrollTop + translateY) {
element.classList.add('show-scroll-indicator-down');
} else {
element.classList.remove('show-scroll-indicator-down');
}
if (scrollTop > 0) {
element.classList.add('show-scroll-indicator-up');
} else {
element.classList.remove('show-scroll-indicator-up');
}
};
Template.studySeriesQuickSwitch.events({
'mouseenter .js-quick-switch, mouseenter .js-quick-switch .switchSectionSeries': function (event, instance) {
instance.$('.quickSwitchWrapper').addClass('overlay');
$(event.currentTarget).addClass('hover');
instance.$('.scrollArea').each(function (index, scrollAreaElement) {
return checkScrollArea(scrollAreaElement);
});
},
'mouseleave .js-quick-switch': function (event, instance) {
instance.$('.js-quick-switch, .switchSectionSeries').removeClass('hover');
instance.$('.quickSwitchWrapper').removeClass('overlay');
},
'click .thumbnailEntry': function (event, instance) {
// Close the quick switch if we have selected a series
instance.$('.js-quick-switch, .switchSectionSeries').removeClass('hover');
instance.$('.quickSwitchWrapper').removeClass('overlay');
},
'click .study-browser-item': function (event, instance) {
instance.$('.switchSectionSeries').addClass('hover');
},
'scroll .scrollArea': function (event) {
checkScrollArea(event.currentTarget);
}
});
Template.studySeriesQuickSwitch.helpers({
// Get the current study
currentStudy: function () {
return Template.instance().data.currentStudy.get();
},
// Check if is Mac OS
// This is necessary due to fix scrollbar space only in browsers in Mac OS:
// Since Lion version, the scrollbar is visible only when user scrolls a div
// As scrollbar is hidden, the space added to hide it in Windows browsers
// is not enough in Mac OS. For WebKit (Safari and Chrome in Mac OS) there is a CSS
// solution using ::-webkit-scrollbar, but unfortunately doesn't work for Firefox
// JS seems to be the only solution for now:
// - http://stackoverflow.com/questions/6165472/custom-css-scrollbar-for-firefox/6165489#6165489
// - http://stackoverflow.com/questions/18317634/force-visible-scrollbar-in-firefox-on-mac-os-x/18318273
isMac: function () {
return window.navigator.appVersion.indexOf('Mac');
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"studyTimepointBrowser":{"template.studyTimepoint.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/studyTimepointBrowser/template.studyTimepoint.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("studyTimepoint");
Template["studyTimepoint"] = new Template("Template.studyTimepoint", (function() {
var view = this;
return HTML.DIV({
class: "studyTimepointWrapper"
}, "\n ", HTML.DIV({
class: "studyTimepoint"
}, "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(view.lookup("studies")),
_variable: "study"
};
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({
study: view.lookup("study"),
active: Spacebars.dataMustache(view.lookup("isActive"), view.lookup("study"))
}));
}, function() {
return Spacebars.include(view.lookupTemplate("studyTimepointStudy"));
}), "\n " ];
}), "\n "), "\n ");
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"studyTimepoint.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepoint.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 1);
Template.studyTimepoint.onCreated(function () {
var instance = Template.instance();
var data = instance.data;
instance.isActive = {};
if (data.isUnassociatedStudy === true && data.studyInstanceUids.length === 1) {
instance.isActive[data.studyInstanceUids[0]] = true;
}
}); // Initialize the timepoint wrapper max-height to enable CSS transition
Template.studyTimepoint.onRendered(function () {
var instance = Template.instance();
var $studies = instance.$('.studyTimepoint');
var $wrapper = $studies.closest('.studyTimepointWrapper');
var $timepoint = $wrapper.closest('.timepoint-item');
var studiesVisible = $studies.is(':visible');
if (!studiesVisible) {
$timepoint.addClass('active');
} // Recalculates the timepoint height to make CSS transition smoother
$studies.trigger('displayStateChanged');
if (!studiesVisible) {
$timepoint.removeClass('active');
}
});
Template.studyTimepoint.events({
// Changes the selected study
'selectionChanged .studyTimepoint': function (event, instance, changed) {
var $selection = $(changed.selection); // Defines where will be the studies searched
var $studiesTarget = instance.$('.studyTimepoint'); // @TypeSafeStudies
if (changed.isQuickSwitch) {
// Changes the current quick switch study
var study = OHIF.viewer.Studies.findBy({
studyInstanceUid: changed.studyInstanceUid
});
instance.data.currentStudy.set(study); // Changes the target to toggle the selection in all the studies
$studiesTarget = $studiesTarget.closest('.studyTimepointBrowser');
} // Removes selected state from all studies but the triggered study
$studiesTarget.find('.study-browser-item').not($selection).removeClass('active');
if (changed.isQuickSwitch) {
// Reset active studies map to allow only one active study
instance.isActive = {}; // Add selected state for the triggered study
$selection.addClass('active');
} else {
var $timepoint = instance.$('.studyTimepoint'); // Set the max-height to inherit to be able to expand the wrapper on its full height
instance.$('.studyTimepointWrapper').css('max-height', 'inherit'); // Toggle selected state for the triggered study
$selection.removeClass('loading');
$selection.toggleClass('active'); // Recalculates the timepoint height to make CSS transition smoother
var $thumbnails = $selection.find('.study-browser-series');
$thumbnails.one('transitionend', function () {
return $timepoint.trigger('displayStateChanged');
});
} // Set the current study as active
instance.isActive[changed.studyInstanceUid] = $selection.hasClass('active');
},
// It should be triggered when the timepoint height is changed
'displayStateChanged .studyTimepoint': function (event, instance) {
var $timepoint = $(event.currentTarget);
var $wrapper = $timepoint.closest('.studyTimepointWrapper'); // Set the max-height for the wrapper to make CSS transition smoother
$wrapper.css('max-height', $timepoint.height());
}
});
Template.studyTimepoint.helpers({
isActive: function (study) {
var instance = Template.instance();
if (!study.studyInstanceUid) {
return;
}
return instance.isActive[study.studyInstanceUid];
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"template.studyTimepointBrowser.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/studyTimepointBrowser/template.studyTimepointBrowser.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("studyTimepointBrowser");
Template["studyTimepointBrowser"] = new Template("Template.studyTimepointBrowser", (function() {
var view = this;
return Blaze.Let({
timepointList: function() {
return Spacebars.call(view.lookup("timepoints"));
}
}, function() {
return [ "\n ", HTML.DIV({
class: function() {
return [ "studyTimepointBrowser noselect ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("shallShowViewType"), view.lookup("timepointList"));
}, function() {
return "viewTypeVisible";
}) ];
}
}, "\n ", HTML.DIV({
class: "timepointButtonContainer p-t-2"
}, "\n ", Blaze._TemplateWith(function() {
return Spacebars.call(view.lookup("viewTypeButtonGroupData"));
}, function() {
return Spacebars.include(view.lookupTemplate("roundedButtonGroup"));
}), "\n "), "\n ", HTML.DIV({
class: "studyTimepointScrollArea"
}, "\n ", HTML.DIV({
class: "p-x-1"
}, "\n ", Blaze.If(function() {
return Spacebars.call(Spacebars.dot(view.lookup("timepointList"), "length"));
}, function() {
return [ "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(view.lookup("timepointList")),
_variable: "timepoint"
};
}, function() {
return [ "\n ", HTML.DIV({
class: "timepoint-browser-item"
}, "\n ", HTML.DIV({
class: "timepoint-item p-y-2"
}, "\n ", HTML.DIV({
class: "timepointHeader"
}, "\n ", HTML.DIV({
class: "timepoint-details clearfix"
}, "\n ", HTML.DIV({
class: "timepoint-title pull-left"
}, "\n ", Blaze.View("lookup:timepointApi.title", function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("timepointApi"), "title"), view.lookup("timepoint"));
}), "\n "), "\n ", HTML.DIV({
class: "timepoint-expand-icon pull-right"
}, "\n ", HTML.I({
class: "fa fa-chevron-down"
}), "\n "), "\n ", HTML.DIV({
class: "timepoint-date pull-right m-r-1"
}, Blaze.View("lookup:formatDA", function() {
return Spacebars.mustache(view.lookup("formatDA"), Spacebars.dot(view.lookup("timepoint"), "earliestDate"), "D-MMM-YYYY");
})), "\n "), "\n ", HTML.DIV({
class: "timepoint-summary"
}, Blaze.View("lookup:modalitiesSummary", function() {
return Spacebars.mustache(view.lookup("modalitiesSummary"), view.lookup("timepoint"));
})), "\n "), "\n ", Blaze._TemplateWith(function() {
return {
studies: Spacebars.call(Spacebars.dataMustache(view.lookup("studies"), view.lookup("timepoint"))),
index: Spacebars.call(view.lookup("@index")),
viewportIndex: Spacebars.call(Spacebars.dot(view.lookup("."), "viewportIndex")),
currentStudy: Spacebars.call(Spacebars.dot(view.lookup("."), "currentStudy"))
};
}, function() {
return Spacebars.include(view.lookupTemplate("studyTimepoint"));
}), "\n "), "\n "), "\n ", HTML.HR(), "\n " ];
}), "\n ", Blaze.If(function() {
return Spacebars.dataMustache(view.lookup("and"), Spacebars.dot(view.lookup("."), "currentStudy"), Spacebars.dataMustache(view.lookup("not"), view.lookup("showAdditionalTimepoints")), view.lookup("hasAdditionalTimepoints"));
}, function() {
return [ "\n ", HTML.DIV({
class: "study-item-box additional"
}, "\n Show additional timepoints\n "), "\n " ];
}), "\n " ];
}, function() {
return [ "\n ", HTML.DIV({
class: "p-t-2"
}, "\n ", Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({
studies: view.lookup("studies")
}));
}, function() {
return Spacebars.include(view.lookupTemplate("studyTimepoint"));
}), "\n "), "\n " ];
}), "\n "), "\n "), "\n "), "\n " ];
});
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"studyTimepointBrowser.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var ReactiveVar;
module.watch(require("meteor/reactive-var"), {
ReactiveVar: function (v) {
ReactiveVar = v;
}
}, 1);
var Tracker;
module.watch(require("meteor/tracker"), {
Tracker: function (v) {
Tracker = v;
}
}, 2);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 3);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 4);
var OHIFError;
module.watch(require("../../../lib/classes/OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 5);
Template.studyTimepointBrowser.onCreated(function () {
var instance = Template.instance(); // Reactive variable to control the view type for all or key timepoints
instance.timepointViewType = new ReactiveVar(instance.data.timepointViewType); // Defines whether to show all key timepoints or only the current one
instance.showAdditionalTimepoints = new ReactiveVar(true); // Return the current study if it's defined
instance.getCurrentStudy = function () {
return instance.data.currentStudy && instance.data.currentStudy.get();
}; // Get the studies for a specific timepoint
instance.getStudies = function (timepoint) {
// @TypeSafeStudies
if (!timepoint) {
return OHIF.viewer.Studies.all();
}
return timepoint.studyInstanceUids.map(function (studyInstanceUid) {
var query = {
studyInstanceUid: studyInstanceUid
};
var loadedStudy = OHIF.viewer.Studies.findBy(query);
if (loadedStudy) return loadedStudy;
var notYetLoaded = OHIF.studylist.collections.Studies.findOne(query);
if (notYetLoaded) return notYetLoaded; // const studyData = _.findWhere(timepoint.studiesData, query);
// if (studyData) return studyData;
throw new OHIFError("No study data available for Study: " + studyInstanceUid);
});
};
});
Template.studyTimepointBrowser.onRendered(function () {
var instance = Template.instance(); // Collapse all timepoints but first when timepoint view type changes
instance.autorun(function () {
// Runs this computation every time the timepointViewType is changed
var type = instance.timepointViewType.get(); // Removes all active classes to collapse the timepoints and studies
instance.$('.timepoint-item, .study-browser-item').removeClass('active');
if (type === 'key' && !instance.data.currentStudy) {
// Show only first timepoint expanded for key timepoints
instance.$('.timepoint-item:first').addClass('active');
}
}); // Expand only the timepoints with loaded studies in viewports
var lastStudy;
var activeStudiesUids = []; // Wait for rerendering and set the timepoint as active
instance.refreshActiveStudies = function () {
return Tracker.afterFlush(function () {
_.each(activeStudiesUids, function (studyInstanceUid) {
instance.$(".study-browser-item[data-uid='" + studyInstanceUid + "']").addClass('active');
}); // Show only first timepoint expanded for key timepoints
instance.$('.timepoint-item:first').addClass('active');
});
};
instance.autorun(function () {
// Runs this computation every time the current study is changed
var currentStudy = instance.data.currentStudy && instance.data.currentStudy.get(); // Stop here if there's no current study set
if (!currentStudy) {
return;
} // Check if the study really changed and update the last study
if (currentStudy !== lastStudy) {
instance.showAdditionalTimepoints.set(false);
lastStudy = currentStudy;
activeStudiesUids = [currentStudy.studyInstanceUid];
}
instance.refreshActiveStudies();
});
});
Template.studyTimepointBrowser.events({
'click .timepointHeader': function (event, instance) {
var $timepoint = $(event.currentTarget).closest('.timepoint-item'); // Recalculates the timepoint height to make CSS transition smoother
$timepoint.find('.studyTimepoint').trigger('displayStateChanged'); // Toggle active class to group/ungroup timepoint studies
$timepoint.toggleClass('active');
},
'click .study-item-box.additional': function (event, instance) {
// Show all key timepoints
instance.showAdditionalTimepoints.set(true);
}
});
Template.studyTimepointBrowser.helpers({
// Decides if the timepoint view type switch shall be shown or omitted
shallShowViewType: function (timepointList) {
var instance = Template.instance();
return timepointList.length && !instance.data.timepointViewType;
},
// Returns the button group data for switching between timepoint view types
viewTypeButtonGroupData: function () {
return {
value: Template.instance().timepointViewType,
options: [{
value: 'key',
text: 'Key Timepoints'
}, {
value: 'all',
text: 'All Timepoints'
}]
};
},
// Defines whether to show all key timepoints or only the current one
showAdditionalTimepoints: function () {
return Template.instance().showAdditionalTimepoints.get();
},
hasAdditionalTimepoints: function () {
var instance = Template.instance();
var timepointApi = instance.data.timepointApi;
var allTimepoints = timepointApi && timepointApi.all();
return allTimepoints && allTimepoints.length > 1;
},
// Get the timepoints to be listed
timepoints: function () {
var instance = Template.instance(); // Get the current study
var currentStudy = instance.getCurrentStudy(); // Declare the timepoints
var timepointApi = instance.data.timepointApi;
var timepoints;
if (currentStudy && !instance.showAdditionalTimepoints.get()) {
// Show only the current study's timepoint
timepoints = timepointApi.study(currentStudy.studyInstanceUid);
} else {
if (!timepointApi) {
// If there is no timepoint API defined whatsoever, this means that there is no
// current timepoint ID, so we can just display all of the currently loaded studies
// in the study sidebar
timepoints = [];
} else if (instance.timepointViewType.get() === 'all') {
// Show all timepoints
timepoints = timepointApi.all();
} else {
// Show only key timepoints
timepoints = timepointApi.key();
}
} // Filter timepoints and show only the current timepoint and previous ones
var result = [];
var currentTimepoint = timepointApi.current();
if (currentTimepoint) {
timepoints.forEach(function (timepoint) {
if (timepoint.latestDate.getTime() <= currentTimepoint.latestDate.getTime()) {
result.push(timepoint);
}
});
} // Returns the timepoints
return result;
},
// Get the studies for a specific timepoint
studies: function (timepoint) {
return Template.instance().getStudies(timepoint);
},
// Build the modalities summary for all timepoint's studies
modalitiesSummary: function (timepoint) {
var instance = Template.instance();
var studies = instance.getStudies(timepoint);
var modalities = {};
studies.forEach(function (study) {
var modality = study.modalities || 'UN';
modalities[modality] = modalities[modality] + 1 || 1;
});
var result = [];
_.each(modalities, function (count, modality) {
result.push(count + " " + modality);
});
return result.join(', ');
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"template.studyTimepointStudy.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/studyTimepointBrowser/template.studyTimepointStudy.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("studyTimepointStudy");
Template["studyTimepointStudy"] = new Template("Template.studyTimepointStudy", (function() {
var view = this;
return Blaze.Let({
isSidebar: function() {
return Spacebars.call(Spacebars.dataMustache(view.lookup("isUndefined"), view.lookup("viewportIndex")));
}
}, function() {
return [ "\n ", HTML.DIV({
class: function() {
return [ "study-browser-item ", Blaze.If(function() {
return Spacebars.call(view.lookup("isSidebar"));
}, function() {
return "studySidebarTimepoint";
}, function() {
return "studyQuickSwitchTimepoint";
}), " ", Blaze.If(function() {
return Spacebars.call(Spacebars.dot(view.lookup("."), "active"));
}, function() {
return "active";
}), " ", Blaze.If(function() {
return Spacebars.call(view.lookup("isLoading"));
}, function() {
return "loading";
}) ];
},
"data-uid": function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("."), "study", "studyInstanceUid"));
}
}, "\n ", HTML.DIV({
class: "study-item"
}, "\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("isLoading"));
}, function() {
return [ "\n ", Spacebars.include(view.lookupTemplate("loadingText")), "\n " ];
}), "\n ", HTML.DIV({
class: "study-item-box"
}, "\n ", HTML.DIV({
class: "study-modality"
}, "\n ", HTML.DIV({
class: "study-modality-text",
style: function() {
return Spacebars.mustache(view.lookup("modalityStyle"));
}
}, "\n ", Blaze.View("lookup:choose", function() {
return Spacebars.mustache(view.lookup("choose"), Spacebars.dot(view.lookup("instance"), "modalities"), "UN");
}), "\n "), "\n "), "\n ", HTML.DIV({
class: "study-text"
}, "\n ", HTML.DIV({
class: "study-date"
}, Blaze.View("lookup:formatDA", function() {
return Spacebars.mustache(view.lookup("formatDA"), Spacebars.dot(view.lookup("instance"), "studyDate"), "D-MMM-YYYY");
})), "\n ", HTML.DIV({
class: "study-description"
}, Blaze.View("lookup:instance.studyDescription", function() {
return Spacebars.mustache(Spacebars.dot(view.lookup("instance"), "studyDescription"));
})), "\n "), "\n "), "\n "), "\n ", Blaze.If(function() {
return Spacebars.call(view.lookup("isSidebar"));
}, function() {
return [ "\n ", HTML.DIV({
class: "study-browser-series"
}, "\n ", HTML.DIV({
class: "study-series-container"
}, "\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.dataMustache(view.lookup("studyThumbnails"), Spacebars.dot(view.lookup("."), "study")),
_variable: "thumbnail"
};
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("clone"), view.lookup("."), Spacebars.kw({
thumbnail: view.lookup("thumbnail")
}));
}, function() {
return Spacebars.include(view.lookupTemplate("thumbnailEntry"));
}), "\n " ];
}), "\n "), "\n "), "\n " ];
}), "\n "), "\n " ];
});
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"studyTimepointStudy.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointStudy.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 1);
var ReactiveVar;
module.watch(require("meteor/reactive-var"), {
ReactiveVar: function (v) {
ReactiveVar = v;
}
}, 2);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 3);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 4);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 5);
Template.studyTimepointStudy.onCreated(function () {
var instance = Template.instance();
instance.loading = new ReactiveVar(false);
var studyMetadata = OHIF.viewerbase.getStudyMetadata(instance.data.study);
var firstInstance = studyMetadata.getFirstInstance();
if (firstInstance) {
instance.modalities = firstInstance.getRawValue('x00080060');
instance.studyDescription = firstInstance.getRawValue('x00081030');
instance.studyDate = firstInstance.getRawValue('x00080020');
} // Get the current study element
instance.getStudyElement = function () {
var isGlobal = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var studyInstanceUid = instance.data.study.studyInstanceUid;
var selector = ".study-browser-item[data-uid='" + studyInstanceUid + "']";
return isGlobal ? $(selector) : instance.$browser.find(selector);
};
instance.isQuickSwitch = function () {
return !_.isUndefined(instance.data.viewportIndex);
}; // Set the current study as selected in the studies list
instance.select = function () {
var isQuickSwitch = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var studyInstanceUid = instance.data.study.studyInstanceUid;
var $study = instance.getStudyElement();
var $timepoint = $study.closest('.studyTimepoint');
var selectionChanged = {
selection: [$study[0]],
studyInstanceUid: studyInstanceUid,
isQuickSwitch: isQuickSwitch
};
$timepoint.trigger('selectionChanged', selectionChanged);
};
instance.initializeStudyWrapper = function () {
// Stop here if it's a quick switch
if (instance.isQuickSwitch()) {
return;
}
var $study = instance.getStudyElement();
var $thumbnails = $study.find('.study-browser-series');
$study.addClass('active'); // If element already has max-height property set, .height()
// will return that value, so remove it to recalculate
$thumbnails.css('max-height', '');
$thumbnails.css('max-height', $thumbnails.height());
$study.removeClass('active'); // Here we add, remove, and add the active class again because this way
// the max-height animation appears smooth to the user.
if (instance.data.active) {
Meteor.setTimeout(function () {
return $study.addClass('active');
}, 1);
}
};
}); // Initialize the study wrapper max-height to enable CSS transition
Template.studyTimepointStudy.onRendered(function () {
var instance = Template.instance(); // Keep the study timepoint browser element to manipulate elements even after DOM is removed
instance.$browser = instance.$('.study-browser-item').closest('.studyTimepointBrowser');
instance.initializeStudyWrapper();
});
Template.studyTimepointStudy.events({
// Recalculates the timepoint height to make CSS transition smoother
'transitionend .study-browser-series': function (event, instance) {
if (event.target === event.currentTarget) {
$(event.currentTarget).closest('.studyTimepoint').trigger('displayStateChanged');
}
},
// Transfers the active state to the current study
'click .studyQuickSwitchTimepoint .study-item-container': function (event, instance) {
instance.select(true);
},
// Set loading state
'loadStarted .study-browser-item': function (event, instance) {
instance.loading.set(true);
},
// Remove loading state and fix the thumbnails wrappers height
'loadEnded .study-browser-item': function (event, instance) {
instance.loading.set(false);
instance.initializeStudyWrapper();
},
// Changes the current study selection for the clicked study
'click .study-item-box': function (event, instance) {
var studyData = instance.data.study;
var studyInstanceUid = studyData.studyInstanceUid;
var isQuickSwitch = instance.isQuickSwitch(); // @TypeSafeStudies
// Check if the study already has series data,
// and if not, retrieve it.
if (!studyData.seriesList) {
var alreadyLoaded = OHIF.viewer.Studies.findBy({
studyInstanceUid: studyInstanceUid
});
if (!alreadyLoaded) {
var $studies = instance.getStudyElement(true);
$studies.trigger('loadStarted');
OHIF.studies.retrieveStudyMetadata(studyInstanceUid).then(function (study) {
instance.data.study = study;
OHIF.viewer.Studies.insert(study);
Meteor.setTimeout(function () {
$studies.trigger('loadEnded');
instance.select(isQuickSwitch);
}, 1);
}).catch(function (error) {
OHIF.log.error("There was an error trying to retrieve the study's metadata for studyInstanceUid: " + studyInstanceUid);
OHIF.log.error(error.stack);
OHIF.log.trace();
});
} else {
studyData.seriesList = alreadyLoaded.seriesList;
instance.select(isQuickSwitch);
}
} else {
instance.select(isQuickSwitch);
}
}
});
Template.studyTimepointStudy.helpers({
isLoading: function () {
// @TypeSafeStudies
var instance = Template.instance();
var studyData = instance.data.study;
var alreadyLoaded = OHIF.viewer.Studies.findBy({
studyInstanceUid: studyData.studyInstanceUid
});
return instance.loading.get() && !alreadyLoaded;
},
modalities: function () {
var instance = Template.instance();
var modalities = instance.modalities || 'UN'; // Replace backslashes with spaces
return modalities.replace(/\\/g, ' ');
},
modalityStyle: function () {
// Responsively styles the Modality Acronyms for studies
// with more than one modality
var instance = Template.instance();
var modalities = instance.modalities || 'UN';
var numModalities = modalities.split(/\\/g).length;
if (numModalities === 1) {
// If we have only one modality, it should take up the whole div.
return 'font-size: 1em';
} else if (numModalities === 2) {
// If we have two, let them sit side-by-side
return 'font-size: 0.75em';
} else {
// If we have more than two modalities, change the line height to display multiple rows,
// depending on the number of modalities we need to display.
var lineHeight = Math.ceil(numModalities / 2) * 1.2;
return 'line-height: ' + lineHeight + 'em';
}
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"windowLevelPresets":{"template.form.js":function(){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/windowLevelPresets/template.form.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
Template.__checkName("windowLevelPresetsForm");
Template["windowLevelPresetsForm"] = new Template("Template.windowLevelPresetsForm", (function() {
var view = this;
return Blaze._TemplateWith(function() {
return Spacebars.dataMustache(view.lookup("extend"), Spacebars.kw({
api: Spacebars.dot(view.lookup("instance"), "api"),
class: "form-themed"
}));
}, function() {
return Spacebars.include(view.lookupTemplate("form"), function() {
return [ "\n ", HTML.DIV({
class: "form-content"
}, "\n ", HTML.TABLE({
class: "full-width"
}, "\n ", HTML.THEAD("\n ", HTML.TR("\n ", HTML.TH({
class: "p-x-1 text-center"
}, "Preset"), "\n ", HTML.TH({
class: "p-x-1"
}, "Description"), "\n ", HTML.TH({
class: "p-x-1"
}, "Window"), "\n ", HTML.TH({
class: "p-x-1"
}, "Level"), "\n "), "\n "), "\n ", HTML.TBODY("\n ", Blaze.Each(function() {
return {
_sequence: Spacebars.call(view.lookup("getPresetsInputInformationList")),
_variable: "presetInputInformation"
};
}, function() {
return [ "\n ", Blaze._TemplateWith(function() {
return {
base: Spacebars.call("baseTr"),
key: Spacebars.call(Spacebars.dataMustache(view.lookup("concat"), view.lookup("@index")))
};
}, function() {
return Spacebars.include(view.lookupTemplate("group"), function() {
return [ "\n ", HTML.TD({
class: "p-x-1 text-center"
}, Blaze.View("lookup:sum", function() {
return Spacebars.mustache(view.lookup("sum"), view.lookup("@index"), 1);
})), "\n ", HTML.TD({
class: "p-x-1"
}, Blaze._TemplateWith(function() {
return {
key: Spacebars.call("id"),
value: Spacebars.call(Spacebars.dot(view.lookup("presetInputInformation"), "id"))
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputText"));
})), "\n ", HTML.TD({
class: "p-x-1"
}, Blaze._TemplateWith(function() {
return {
key: Spacebars.call("ww"),
value: Spacebars.call(Spacebars.dataMustache(view.lookup("filterNaN"), Spacebars.dot(view.lookup("presetInputInformation"), "ww"))),
dataType: Spacebars.call("Number")
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputText"));
})), "\n ", HTML.TD({
class: "p-x-1"
}, Blaze._TemplateWith(function() {
return {
key: Spacebars.call("wc"),
value: Spacebars.call(Spacebars.dataMustache(view.lookup("filterNaN"), Spacebars.dot(view.lookup("presetInputInformation"), "wc"))),
dataType: Spacebars.call("Number")
};
}, function() {
return Spacebars.include(view.lookupTemplate("inputText"));
})), "\n " ];
});
}), "\n " ];
}), "\n "), "\n "), "\n "), "\n ", HTML.DIV({
class: "form-buttons clearfix"
}, "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("btn btn-danger pull-left"),
action: Spacebars.call("resetDefaults")
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return "Reset to Defaults";
});
}), "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("btn btn-primary pull-right"),
action: Spacebars.call("save")
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return "Save";
});
}), "\n ", Blaze._TemplateWith(function() {
return {
class: Spacebars.call("btn btn-secondary pull-right m-r-1"),
tagAttributes: Spacebars.call(Spacebars.dataMustache(view.lookup("extend"), "", Spacebars.kw({
"data-dismiss": "modal"
})))
};
}, function() {
return Spacebars.include(view.lookupTemplate("button"), function() {
return "Close";
});
}), "\n "), "\n " ];
});
});
}));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"form.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/components/viewer/windowLevelPresets/form.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 1);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 2);
Template.windowLevelPresetsForm.onCreated(function () {
var instance = Template.instance();
var wlPresets = OHIF.viewerbase.wlPresets;
instance.api = {
save: function () {
var form = instance.$('form').first().data('component');
var definitions = form.value();
var promise = wlPresets.store(definitions);
promise.then(function () {
return OHIF.ui.notifications.success({
text: 'The Window/Levels preferences were successfully saved.'
});
});
return promise;
},
resetDefaults: function () {
var dialogOptions = {
"class": 'themed',
title: 'Reset Window/Levels Presets',
message: 'Are you sure you want to reset all the window level presets to their defaults?'
};
return OHIF.ui.showDialog('dialogConfirm', dialogOptions).then(function () {
return wlPresets.resetDefaults();
});
}
};
});
Template.windowLevelPresetsForm.helpers({
getPresetsInputInformationList: function () {
OHIF.viewerbase.wlPresets.changeObserver.depend();
return _.toArray(OHIF.viewer.wlPresets);
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}}}},"collections.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/collections.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var OHIF;
module.watch(require("../namespace"), {
OHIF: function (v) {
OHIF = v;
}
}, 1);
var TypeSafeCollection;
module.watch(require("./lib/classes/TypeSafeCollection"), {
TypeSafeCollection: function (v) {
TypeSafeCollection = v;
}
}, 2);
// Create main Studies collection which will be used across the entire viewer...
var Studies = new TypeSafeCollection(); // Make it publicly available on "OHIF.viewer" namespace...
OHIF.viewer.Studies = Studies; // Create main StudyMetadataList collection which will be used across the entire viewer...
var StudyMetadataList = new TypeSafeCollection(); // Make it publicly available on "OHIF.viewer" namespace...
OHIF.viewer.StudyMetadataList = StudyMetadataList; // Subscriptions...
Meteor.subscribe('studyImportStatus');
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"index.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/index.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Viewerbase;
module.watch(require("../namespace"), {
Viewerbase: function (v) {
Viewerbase = v;
}
}, 0);
module.watch(require("./collections"));
module.watch(require("./lib/debugReactivity"));
var getElementIfNotEmpty;
module.watch(require("./lib/getElementIfNotEmpty"), {
getElementIfNotEmpty: function (v) {
getElementIfNotEmpty = v;
}
}, 1);
var getStackDataIfNotEmpty;
module.watch(require("./lib/getStackDataIfNotEmpty"), {
getStackDataIfNotEmpty: function (v) {
getStackDataIfNotEmpty = v;
}
}, 2);
var switchToImageRelative;
module.watch(require("./lib/switchToImageRelative"), {
switchToImageRelative: function (v) {
switchToImageRelative = v;
}
}, 3);
var switchToImageByIndex;
module.watch(require("./lib/switchToImageByIndex"), {
switchToImageByIndex: function (v) {
switchToImageByIndex = v;
}
}, 4);
var getFrameOfReferenceUID;
module.watch(require("./lib/getFrameOfReferenceUID"), {
getFrameOfReferenceUID: function (v) {
getFrameOfReferenceUID = v;
}
}, 5);
var getImageIdForImagePath;
module.watch(require("./lib/getImageIdForImagePath"), {
getImageIdForImagePath: function (v) {
getImageIdForImagePath = v;
}
}, 6);
var updateCrosshairsSynchronizer;
module.watch(require("./lib/updateCrosshairsSynchronizer"), {
updateCrosshairsSynchronizer: function (v) {
updateCrosshairsSynchronizer = v;
}
}, 7);
var getImageId;
module.watch(require("./lib/getImageId"), {
getImageId: function (v) {
getImageId = v;
}
}, 8);
var setActiveViewport;
module.watch(require("./lib/setActiveViewport"), {
setActiveViewport: function (v) {
setActiveViewport = v;
}
}, 9);
var setFocusToActiveViewport;
module.watch(require("./lib/setFocusToActiveViewport"), {
setFocusToActiveViewport: function (v) {
setFocusToActiveViewport = v;
}
}, 10);
var getWADORSImageId;
module.watch(require("./lib/getWADORSImageId"), {
getWADORSImageId: function (v) {
getWADORSImageId = v;
}
}, 11);
var updateAllViewports;
module.watch(require("./lib/updateAllViewports"), {
updateAllViewports: function (v) {
updateAllViewports = v;
}
}, 12);
var sortStudy;
module.watch(require("./lib/sortStudy"), {
sortStudy: function (v) {
sortStudy = v;
}
}, 13);
var updateMetaDataManager;
module.watch(require("./lib/updateMetaDataManager"), {
updateMetaDataManager: function (v) {
updateMetaDataManager = v;
}
}, 14);
var updateOrientationMarkers;
module.watch(require("./lib/updateOrientationMarkers"), {
updateOrientationMarkers: function (v) {
updateOrientationMarkers = v;
}
}, 15);
var isImage;
module.watch(require("./lib/isImage"), {
isImage: function (v) {
isImage = v;
}
}, 16);
var getInstanceClassDefaultViewport, setInstanceClassDefaultViewportFunction;
module.watch(require("./lib/instanceClassSpecificViewport"), {
getInstanceClassDefaultViewport: function (v) {
getInstanceClassDefaultViewport = v;
},
setInstanceClassDefaultViewportFunction: function (v) {
setInstanceClassDefaultViewportFunction = v;
}
}, 17);
var displayReferenceLines;
module.watch(require("./lib/displayReferenceLines"), {
displayReferenceLines: function (v) {
displayReferenceLines = v;
}
}, 18);
var getStudyMetadata;
module.watch(require("./lib/getStudyMetadata"), {
getStudyMetadata: function (v) {
getStudyMetadata = v;
}
}, 19);
var imageViewerViewportData;
module.watch(require("./lib/imageViewerViewportData"), {
imageViewerViewportData: function (v) {
imageViewerViewportData = v;
}
}, 20);
var panelNavigation;
module.watch(require("./lib/panelNavigation"), {
panelNavigation: function (v) {
panelNavigation = v;
}
}, 21);
var prepareViewerData;
module.watch(require("./lib/prepareViewerData"), {
prepareViewerData: function (v) {
prepareViewerData = v;
}
}, 22);
var renderViewer;
module.watch(require("./lib/renderViewer"), {
renderViewer: function (v) {
renderViewer = v;
}
}, 23);
var WLPresets;
module.watch(require("./lib/WLPresets"), {
WLPresets: function (v) {
WLPresets = v;
}
}, 24);
var hotkeyUtils;
module.watch(require("./lib/hotkeyUtils"), {
hotkeyUtils: function (v) {
hotkeyUtils = v;
}
}, 25);
var viewportOverlayUtils;
module.watch(require("./lib/viewportOverlayUtils"), {
viewportOverlayUtils: function (v) {
viewportOverlayUtils = v;
}
}, 26);
var viewportUtils;
module.watch(require("./lib/viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 27);
var thumbnailDragHandlers;
module.watch(require("./lib/thumbnailDragHandlers"), {
thumbnailDragHandlers: function (v) {
thumbnailDragHandlers = v;
}
}, 28);
var dialogUtils;
module.watch(require("./lib/dialogUtils"), {
dialogUtils: function (v) {
dialogUtils = v;
}
}, 29);
var unloadHandlers;
module.watch(require("./lib/unloadHandlers"), {
unloadHandlers: function (v) {
unloadHandlers = v;
}
}, 30);
var sortingManager;
module.watch(require("./lib/sortingManager"), {
sortingManager: function (v) {
sortingManager = v;
}
}, 31);
var crosshairsSynchronizers;
module.watch(require("./lib/crosshairsSynchronizers"), {
crosshairsSynchronizers: function (v) {
crosshairsSynchronizers = v;
}
}, 32);
var annotateTextUtils;
module.watch(require("./lib/annotateTextUtils"), {
annotateTextUtils: function (v) {
annotateTextUtils = v;
}
}, 33);
var textMarkerUtils;
module.watch(require("./lib/textMarkerUtils"), {
textMarkerUtils: function (v) {
textMarkerUtils = v;
}
}, 34);
var createStacks;
module.watch(require("./lib/createStacks"), {
createStacks: function (v) {
createStacks = v;
}
}, 35);
var StackManager;
module.watch(require("./lib/StackManager"), {
StackManager: function (v) {
StackManager = v;
}
}, 36);
var toolManager;
module.watch(require("./lib/toolManager"), {
toolManager: function (v) {
toolManager = v;
}
}, 37);
var helpers;
module.watch(require("./lib/helpers/"), {
helpers: function (v) {
helpers = v;
}
}, 38);
var sopClassDictionary;
module.watch(require("./lib/sopClassDictionary"), {
sopClassDictionary: function (v) {
sopClassDictionary = v;
}
}, 39);
var DICOMTagDescriptions;
module.watch(require("./lib/DICOMTagDescriptions"), {
DICOMTagDescriptions: function (v) {
DICOMTagDescriptions = v;
}
}, 40);
var ImageSet;
module.watch(require("./lib/classes/ImageSet"), {
ImageSet: function (v) {
ImageSet = v;
}
}, 41);
var LayoutManager;
module.watch(require("./lib/classes/LayoutManager"), {
LayoutManager: function (v) {
LayoutManager = v;
}
}, 42);
var StudyPrefetcher;
module.watch(require("./lib/classes/StudyPrefetcher"), {
StudyPrefetcher: function (v) {
StudyPrefetcher = v;
}
}, 43);
var ResizeViewportManager;
module.watch(require("./lib/classes/ResizeViewportManager"), {
ResizeViewportManager: function (v) {
ResizeViewportManager = v;
}
}, 44);
var StudyLoadingListener;
module.watch(require("./lib/classes/StudyLoadingListener"), {
StudyLoadingListener: function (v) {
StudyLoadingListener = v;
}
}, 45);
var StackLoadingListener;
module.watch(require("./lib/classes/StudyLoadingListener"), {
StackLoadingListener: function (v) {
StackLoadingListener = v;
}
}, 46);
var DICOMFileLoadingListener;
module.watch(require("./lib/classes/StudyLoadingListener"), {
DICOMFileLoadingListener: function (v) {
DICOMFileLoadingListener = v;
}
}, 47);
var StudyMetadata;
module.watch(require("./lib/classes/metadata/StudyMetadata"), {
StudyMetadata: function (v) {
StudyMetadata = v;
}
}, 48);
var SeriesMetadata;
module.watch(require("./lib/classes/metadata/SeriesMetadata"), {
SeriesMetadata: function (v) {
SeriesMetadata = v;
}
}, 49);
var InstanceMetadata;
module.watch(require("./lib/classes/metadata/InstanceMetadata"), {
InstanceMetadata: function (v) {
InstanceMetadata = v;
}
}, 50);
var StudySummary;
module.watch(require("./lib/classes/metadata/StudySummary"), {
StudySummary: function (v) {
StudySummary = v;
}
}, 51);
var plugins;
module.watch(require("./lib/classes/plugins/"), {
plugins: function (v) {
plugins = v;
}
}, 52);
var TypeSafeCollection;
module.watch(require("./lib/classes/TypeSafeCollection"), {
TypeSafeCollection: function (v) {
TypeSafeCollection = v;
}
}, 53);
var OHIFError;
module.watch(require("./lib/classes/OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 54);
var StackImagePositionOffsetSynchronizer;
module.watch(require("./lib/classes/StackImagePositionOffsetSynchronizer"), {
StackImagePositionOffsetSynchronizer: function (v) {
StackImagePositionOffsetSynchronizer = v;
}
}, 55);
var StudyMetadataSource;
module.watch(require("./lib/classes/StudyMetadataSource"), {
StudyMetadataSource: function (v) {
StudyMetadataSource = v;
}
}, 56);
Viewerbase.getElementIfNotEmpty = getElementIfNotEmpty; // getStackDataIfNotEmpty
Viewerbase.getStackDataIfNotEmpty = getStackDataIfNotEmpty; // switchToImageRelative
Viewerbase.switchToImageRelative = switchToImageRelative; // switchToImageByIndex
Viewerbase.switchToImageByIndex = switchToImageByIndex; // getFrameOfReferenceUID
Viewerbase.getFrameOfReferenceUID = getFrameOfReferenceUID; // getImageIdForImagePath
Viewerbase.getImageIdForImagePath = getImageIdForImagePath; // updateCrosshairsSynchronizer
Viewerbase.updateCrosshairsSynchronizer = updateCrosshairsSynchronizer; // getImageId
Viewerbase.getImageId = getImageId; // setActiveViewport
Viewerbase.setActiveViewport = setActiveViewport; // setFocusToActiveViewport
Viewerbase.setFocusToActiveViewport = setFocusToActiveViewport; // getWADORSImageId
Viewerbase.getWADORSImageId = getWADORSImageId; // updateAllViewports
Viewerbase.updateAllViewports = updateAllViewports; // sortStudy
Viewerbase.sortStudy = sortStudy; // updateMetaDataManager
Viewerbase.updateMetaDataManager = updateMetaDataManager; // updateOrientationMarkers
Viewerbase.updateOrientationMarkers = updateOrientationMarkers; // isImage
Viewerbase.isImage = isImage; // getInstanceClassDefaultViewport, setInstanceClassDefaultViewportFunction
Viewerbase.getInstanceClassDefaultViewport = getInstanceClassDefaultViewport;
Viewerbase.setInstanceClassDefaultViewportFunction = setInstanceClassDefaultViewportFunction; // displayReferenceLines
Viewerbase.displayReferenceLines = displayReferenceLines; // getStudyMetadata
Viewerbase.getStudyMetadata = getStudyMetadata;
/**
* Exported Namespaces (sub-namespaces)
*/
// imageViewerViewportData.*
Viewerbase.imageViewerViewportData = imageViewerViewportData; // panelNavigation.*
Viewerbase.panelNavigation = panelNavigation; // prepareViewerData
Viewerbase.prepareViewerData = prepareViewerData; // renderViewer
Viewerbase.renderViewer = renderViewer; // WLPresets.*
Viewerbase.wlPresets = WLPresets; // hotkeyUtils.*
Viewerbase.hotkeyUtils = hotkeyUtils; // viewportOverlayUtils.*
Viewerbase.viewportOverlayUtils = viewportOverlayUtils; // viewportUtils.*
Viewerbase.viewportUtils = viewportUtils; // thumbnailDragHandlers.*
Viewerbase.thumbnailDragHandlers = thumbnailDragHandlers; // dialogUtils.*
Viewerbase.dialogUtils = dialogUtils; // unloadHandlers.*
Viewerbase.unloadHandlers = unloadHandlers; // sortingManager.*
Viewerbase.sortingManager = sortingManager; // crosshairsSynchronizers.*
Viewerbase.crosshairsSynchronizers = crosshairsSynchronizers; // annotateTextUtils.*
Viewerbase.annotateTextUtils = annotateTextUtils; // textMarkerUtils.*
Viewerbase.textMarkerUtils = textMarkerUtils; // createStacks.*
Viewerbase.createStacks = createStacks;
/**
* Exported Singletons
*/
// StackManager as "stackManager" (since it's a plain object instance, the exported name starts with a lowercase letter)
Viewerbase.stackManager = StackManager; // toolManager
Viewerbase.toolManager = toolManager;
/**
* Exported Helpers
*/
Viewerbase.helpers = helpers;
/**
* Exported Collections
*/
// sopClassDictionary
Viewerbase.sopClassDictionary = sopClassDictionary; // dicomTagDescriptions
Viewerbase.DICOMTagDescriptions = DICOMTagDescriptions;
/**
* Exported Classes
*/
// ImageSet
Viewerbase.ImageSet = ImageSet; // LayoutManager
Viewerbase.LayoutManager = LayoutManager; // StudyPrefetcher
Viewerbase.StudyPrefetcher = StudyPrefetcher; // ResizeViewportManager
Viewerbase.ResizeViewportManager = ResizeViewportManager; // StudyLoadingListener
Viewerbase.StudyLoadingListener = StudyLoadingListener; // StackLoadingListener
Viewerbase.StackLoadingListener = StackLoadingListener; // DICOMFileLoadingListener
Viewerbase.DICOMFileLoadingListener = DICOMFileLoadingListener; // StudyMetadata, SeriesMetadata, InstanceMetadata
Viewerbase.metadata = {
StudyMetadata: StudyMetadata,
SeriesMetadata: SeriesMetadata,
InstanceMetadata: InstanceMetadata,
StudySummary: StudySummary
};
Viewerbase.plugins = plugins; // TypeSafeCollection
Viewerbase.TypeSafeCollection = TypeSafeCollection; // OHIFError
Viewerbase.OHIFError = OHIFError; // StackImagePositionOffsetSynchronizer
Viewerbase.StackImagePositionOffsetSynchronizer = StackImagePositionOffsetSynchronizer; // StudyMetadataSource
Viewerbase.StudyMetadataSource = StudyMetadataSource;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"lib":{"DICOMTagDescriptions.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/DICOMTagDescriptions.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
module.export({
DICOMTagDescriptions: function () {
return DICOMTagDescriptions;
}
});
var NUMBER = 'number';
var STRING = 'string';
var REGEX_TAG = /^x[0-9a-fx]{8}$/;
var DICOMTagDescriptions = Object.create(Object.prototype, {
_descriptions: {
configurable: false,
enumerable: false,
writable: false,
value: Object.create(null)
},
tagNumberToString: {
configurable: false,
enumerable: true,
writable: false,
value: function () {
function tagNumberToString(tag) {
var string; // by default, undefined is returned...
if (this.isValidTagNumber(tag)) {
// if it's a number, build its hexadecimal representation...
string = 'x' + ('00000000' + tag.toString(16)).substr(-8);
}
return string;
}
return tagNumberToString;
}()
},
isValidTagNumber: {
configurable: false,
enumerable: true,
writable: false,
value: function () {
function isValidTagNumber(tag) {
return (0, _typeof2.default)(tag) === NUMBER && tag >= 0 && tag <= 0xFFFFFFFF;
}
return isValidTagNumber;
}()
},
isValidTag: {
configurable: false,
enumerable: true,
writable: false,
value: function () {
function isValidTag(tag) {
return (0, _typeof2.default)(tag) === STRING ? REGEX_TAG.test(tag) : this.isValidTagNumber(tag);
}
return isValidTag;
}()
},
find: {
configurable: false,
enumerable: true,
writable: false,
value: function () {
function find(name) {
var description; // by default, undefined is returned...
if ((0, _typeof2.default)(name) !== STRING) {
// if it's a number, a tag string will be returned...
name = this.tagNumberToString(name);
}
if ((0, _typeof2.default)(name) === STRING) {
description = this._descriptions[name];
}
return description;
}
return find;
}()
},
init: {
configurable: false,
enumerable: true,
writable: false,
value: function () {
function init(descriptionMap) {
var _hasOwn = Object.prototype.hasOwnProperty;
var _descriptions = this._descriptions;
for (var tag in meteorBabelHelpers.sanitizeForInObject(descriptionMap)) {
if (_hasOwn.call(descriptionMap, tag)) {
if (!this.isValidTag(tag)) {
// Skip in case tag is not valid...
console.info("DICOMTagDescriptions: Invalid tag \"" + tag + "\"...");
continue;
}
if (tag in _descriptions) {
// Skip in case the tag is duplicated...
console.info("DICOMTagDescriptions: Duplicated tag \"" + tag + "\"...");
continue;
} // Save keyword...
var keyword = descriptionMap[tag]; // Create a description entry and freeze it...
var entry = Object.create(null);
entry.tag = tag;
entry.keyword = keyword;
Object.freeze(entry); // Add tag references to entry...
_descriptions[tag] = entry; // Add keyword references to entry (if not present already)...
if (keyword in _descriptions) {
var currentEntry = _descriptions[keyword];
console.info("DICOMTagDescriptions: Using <" + currentEntry.tag + "," + currentEntry.keyword + "> instead of <" + entry.tag + "," + entry.keyword + "> for keyword \"" + keyword + "\"...");
} else {
_descriptions[keyword] = entry;
}
}
} // Freeze internal description map...
Object.freeze(_descriptions); // Freeze itself...
Object.freeze(this);
}
return init;
}()
}
});
/**
* Map with DICOM Tag Descriptions
*/
var initialTagDescriptionMap = {
x00020000: 'FileMetaInfoGroupLength',
x00020001: 'FileMetaInfoVersion',
x00020002: 'MediaStorageSOPClassUID',
x00020003: 'MediaStorageSOPInstanceUID',
x00020010: 'TransferSyntaxUID',
x00020012: 'ImplementationClassUID',
x00020013: 'ImplementationVersionName',
x00020016: 'SourceApplicationEntityTitle',
x00020100: 'PrivateInformationCreatorUID',
x00020102: 'PrivateInformation',
x00041130: 'FileSetID',
x00041141: 'FileSetDescriptorFileID',
x00041142: 'SpecificCharacterSetOfFile',
x00041200: 'FirstDirectoryRecordOffset',
x00041202: 'LastDirectoryRecordOffset',
x00041212: 'FileSetConsistencyFlag',
x00041220: 'DirectoryRecordSequence',
x00041400: 'OffsetOfNextDirectoryRecord',
x00041410: 'RecordInUseFlag',
x00041420: 'LowerLevelDirectoryEntityOffset',
x00041430: 'DirectoryRecordType',
x00041432: 'PrivateRecordUID',
x00041500: 'ReferencedFileID',
x00041504: 'MRDRDirectoryRecordOffset',
x00041510: 'ReferencedSOPClassUIDInFile',
x00041511: 'ReferencedSOPInstanceUIDInFile',
x00041512: 'ReferencedTransferSyntaxUIDInFile',
x0004151a: 'ReferencedRelatedSOPClassUIDInFile',
x00041600: 'NumberOfReferences',
x00080000: 'IdentifyingGroupLength',
x00080001: 'LengthToEnd',
x00080005: 'SpecificCharacterSet',
x00080006: 'LanguageCodeSequence',
x00080008: 'ImageType',
x00080010: 'RecognitionCode',
x00080012: 'InstanceCreationDate',
x00080013: 'InstanceCreationTime',
x00080014: 'InstanceCreatorUID',
x00080016: 'SOPClassUID',
x00080018: 'SOPInstanceUID',
x0008001a: 'RelatedGeneralSOPClassUID',
x0008001b: 'OriginalSpecializedSOPClassUID',
x00080020: 'StudyDate',
x00080021: 'SeriesDate',
x00080022: 'AcquisitionDate',
x00080023: 'ContentDate',
x00080024: 'OverlayDate',
x00080025: 'CurveDate',
x0008002a: 'AcquisitionDateTime',
x00080030: 'StudyTime',
x00080031: 'SeriesTime',
x00080032: 'AcquisitionTime',
x00080033: 'ContentTime',
x00080034: 'OverlayTime',
x00080035: 'CurveTime',
x00080040: 'DataSetType',
x00080041: 'DataSetSubtype',
x00080042: 'NuclearMedicineSeriesType',
x00080050: 'AccessionNumber',
x00080052: 'QueryRetrieveLevel',
x00080054: 'RetrieveAETitle',
x00080056: 'InstanceAvailability',
x00080058: 'FailedSOPInstanceUIDList',
x00080060: 'Modality',
x00080061: 'ModalitiesInStudy',
x00080062: 'SOPClassesInStudy',
x00080064: 'ConversionType',
x00080068: 'PresentationIntentType',
x00080070: 'Manufacturer',
x00080080: 'InstitutionName',
x00080081: 'InstitutionAddress',
x00080082: 'InstitutionCodeSequence',
x00080090: 'ReferringPhysicianName',
x00080092: 'ReferringPhysicianAddress',
x00080094: 'ReferringPhysicianTelephoneNumber',
x00080096: 'ReferringPhysicianIDSequence',
x00080100: 'CodeValue',
x00080102: 'CodingSchemeDesignator',
x00080103: 'CodingSchemeVersion',
x00080104: 'CodeMeaning',
x00080105: 'MappingResource',
x00080106: 'ContextGroupVersion',
x00080107: 'ContextGroupLocalVersion',
x0008010b: 'ContextGroupExtensionFlag',
x0008010c: 'CodingSchemeUID',
x0008010d: 'ContextGroupExtensionCreatorUID',
x0008010f: 'ContextIdentifier',
x00080110: 'CodingSchemeIDSequence',
x00080112: 'CodingSchemeRegistry',
x00080114: 'CodingSchemeExternalID',
x00080115: 'CodingSchemeName',
x00080116: 'CodingSchemeResponsibleOrganization',
x00080117: 'ContextUID',
x00080201: 'TimezoneOffsetFromUTC',
x00081000: 'NetworkID',
x00081010: 'StationName',
x00081030: 'StudyDescription',
x00081032: 'ProcedureCodeSequence',
x0008103e: 'SeriesDescription',
x00081040: 'InstitutionalDepartmentName',
x00081048: 'PhysiciansOfRecord',
x00081049: 'PhysiciansOfRecordIDSequence',
x00081050: 'PerformingPhysicianName',
x00081052: 'PerformingPhysicianIDSequence',
x00081060: 'NameOfPhysicianReadingStudy',
x00081062: 'PhysicianReadingStudyIDSequence',
x00081070: 'OperatorsName',
x00081072: 'OperatorIDSequence',
x00081080: 'AdmittingDiagnosesDescription',
x00081084: 'AdmittingDiagnosesCodeSequence',
x00081090: 'ManufacturersModelName',
x00081100: 'ReferencedResultsSequence',
x00081110: 'ReferencedStudySequence',
x00081111: 'ReferencedPerformedProcedureStepSequence',
x00081115: 'ReferencedSeriesSequence',
x00081120: 'ReferencedPatientSequence',
x00081125: 'ReferencedVisitSequence',
x00081130: 'ReferencedOverlaySequence',
x0008113a: 'ReferencedWaveformSequence',
x00081140: 'ReferencedImageSequence',
x00081145: 'ReferencedCurveSequence',
x0008114a: 'ReferencedInstanceSequence',
x00081150: 'ReferencedSOPClassUID',
x00081155: 'ReferencedSOPInstanceUID',
x0008115a: 'SOPClassesSupported',
x00081160: 'ReferencedFrameNumber',
x00081161: 'SimpleFrameList',
x00081162: 'CalculatedFrameList',
x00081163: 'TimeRange',
x00081164: 'FrameExtractionSequence',
x00081195: 'TransactionUID',
x00081197: 'FailureReason',
x00081198: 'FailedSOPSequence',
x00081199: 'ReferencedSOPSequence',
x00081200: 'OtherReferencedStudiesSequence',
x00081250: 'RelatedSeriesSequence',
x00082110: 'LossyImageCompressionRetired',
x00082111: 'DerivationDescription',
x00082112: 'SourceImageSequence',
x00082120: 'StageName',
x00082122: 'StageNumber',
x00082124: 'NumberOfStages',
x00082127: 'ViewName',
x00082128: 'ViewNumber',
x00082129: 'NumberOfEventTimers',
x0008212a: 'NumberOfViewsInStage',
x00082130: 'EventElapsedTimes',
x00082132: 'EventTimerNames',
x00082133: 'EventTimerSequence',
x00082134: 'EventTimeOffset',
x00082135: 'EventCodeSequence',
x00082142: 'StartTrim',
x00082143: 'StopTrim',
x00082144: 'RecommendedDisplayFrameRate',
x00082200: 'TransducerPosition',
x00082204: 'TransducerOrientation',
x00082208: 'AnatomicStructure',
x00082218: 'AnatomicRegionSequence',
x00082220: 'AnatomicRegionModifierSequence',
x00082228: 'PrimaryAnatomicStructureSequence',
x00082229: 'AnatomicStructureOrRegionSequence',
x00082230: 'AnatomicStructureModifierSequence',
x00082240: 'TransducerPositionSequence',
x00082242: 'TransducerPositionModifierSequence',
x00082244: 'TransducerOrientationSequence',
x00082246: 'TransducerOrientationModifierSeq',
x00082253: 'AnatomicEntrancePortalCodeSeqTrial',
x00082255: 'AnatomicApproachDirCodeSeqTrial',
x00082256: 'AnatomicPerspectiveDescrTrial',
x00082257: 'AnatomicPerspectiveCodeSeqTrial',
x00083001: 'AlternateRepresentationSequence',
x00083010: 'IrradiationEventUID',
x00084000: 'IdentifyingComments',
x00089007: 'FrameType',
x00089092: 'ReferencedImageEvidenceSequence',
x00089121: 'ReferencedRawDataSequence',
x00089123: 'CreatorVersionUID',
x00089124: 'DerivationImageSequence',
x00089154: 'SourceImageEvidenceSequence',
x00089205: 'PixelPresentation',
x00089206: 'VolumetricProperties',
x00089207: 'VolumeBasedCalculationTechnique',
x00089208: 'ComplexImageComponent',
x00089209: 'AcquisitionContrast',
x00089215: 'DerivationCodeSequence',
x00089237: 'GrayscalePresentationStateSequence',
x00089410: 'ReferencedOtherPlaneSequence',
x00089458: 'FrameDisplaySequence',
x00089459: 'RecommendedDisplayFrameRateInFloat',
x00089460: 'SkipFrameRangeFlag',
// x00091001: 'FullFidelity',
// x00091002: 'SuiteID',
// x00091004: 'ProductID',
// x00091027: 'ImageActualDate',
// x00091030: 'ServiceID',
// x00091031: 'MobileLocationNumber',
// x000910e3: 'EquipmentUID',
// x000910e6: 'GenesisVersionNow',
// x000910e7: 'ExamRecordChecksum',
// x000910e9: 'ActualSeriesDataTimeStamp',
x00100000: 'PatientGroupLength',
x00100010: 'PatientName',
x00100020: 'PatientID',
x00100021: 'IssuerOfPatientID',
x00100022: 'TypeOfPatientID',
x00100030: 'PatientBirthDate',
x00100032: 'PatientBirthTime',
x00100040: 'PatientSex',
x00100050: 'PatientInsurancePlanCodeSequence',
x00100101: 'PatientPrimaryLanguageCodeSeq',
x00100102: 'PatientPrimaryLanguageCodeModSeq',
x00101000: 'OtherPatientIDs',
x00101001: 'OtherPatientNames',
x00101002: 'OtherPatientIDsSequence',
x00101005: 'PatientBirthName',
x00101010: 'PatientAge',
x00101020: 'PatientSize',
x00101030: 'PatientWeight',
x00101040: 'PatientAddress',
x00101050: 'InsurancePlanIdentification',
x00101060: 'PatientMotherBirthName',
x00101080: 'MilitaryRank',
x00101081: 'BranchOfService',
x00101090: 'MedicalRecordLocator',
x00102000: 'MedicalAlerts',
x00102110: 'Allergies',
x00102150: 'CountryOfResidence',
x00102152: 'RegionOfResidence',
x00102154: 'PatientTelephoneNumbers',
x00102160: 'EthnicGroup',
x00102180: 'Occupation',
x001021a0: 'SmokingStatus',
x001021b0: 'AdditionalPatientHistory',
x001021c0: 'PregnancyStatus',
x001021d0: 'LastMenstrualDate',
x001021f0: 'PatientReligiousPreference',
x00102201: 'PatientSpeciesDescription',
x00102202: 'PatientSpeciesCodeSequence',
x00102203: 'PatientSexNeutered',
x00102210: 'AnatomicalOrientationType',
x00102292: 'PatientBreedDescription',
x00102293: 'PatientBreedCodeSequence',
x00102294: 'BreedRegistrationSequence',
x00102295: 'BreedRegistrationNumber',
x00102296: 'BreedRegistryCodeSequence',
x00102297: 'ResponsiblePerson',
x00102298: 'ResponsiblePersonRole',
x00102299: 'ResponsibleOrganization',
x00104000: 'PatientComments',
x00109431: 'ExaminedBodyThickness',
x00111010: 'PatientStatus',
x00120010: 'ClinicalTrialSponsorName',
x00120020: 'ClinicalTrialProtocolID',
x00120021: 'ClinicalTrialProtocolName',
x00120030: 'ClinicalTrialSiteID',
x00120031: 'ClinicalTrialSiteName',
x00120040: 'ClinicalTrialSubjectID',
x00120042: 'ClinicalTrialSubjectReadingID',
x00120050: 'ClinicalTrialTimePointID',
x00120051: 'ClinicalTrialTimePointDescription',
x00120060: 'ClinicalTrialCoordinatingCenter',
x00120062: 'PatientIdentityRemoved',
x00120063: 'DeidentificationMethod',
x00120064: 'DeidentificationMethodCodeSequence',
x00120071: 'ClinicalTrialSeriesID',
x00120072: 'ClinicalTrialSeriesDescription',
x00120084: 'DistributionType',
x00120085: 'ConsentForDistributionFlag',
x00180000: 'AcquisitionGroupLength',
x00180010: 'ContrastBolusAgent',
x00180012: 'ContrastBolusAgentSequence',
x00180014: 'ContrastBolusAdministrationRoute',
x00180015: 'BodyPartExamined',
x00180020: 'ScanningSequence',
x00180021: 'SequenceVariant',
x00180022: 'ScanOptions',
x00180023: 'MRAcquisitionType',
x00180024: 'SequenceName',
x00180025: 'AngioFlag',
x00180026: 'InterventionDrugInformationSeq',
x00180027: 'InterventionDrugStopTime',
x00180028: 'InterventionDrugDose',
x00180029: 'InterventionDrugSequence',
x0018002a: 'AdditionalDrugSequence',
x00180030: 'Radionuclide',
x00180031: 'Radiopharmaceutical',
x00180032: 'EnergyWindowCenterline',
x00180033: 'EnergyWindowTotalWidth',
x00180034: 'InterventionDrugName',
x00180035: 'InterventionDrugStartTime',
x00180036: 'InterventionSequence',
x00180037: 'TherapyType',
x00180038: 'InterventionStatus',
x00180039: 'TherapyDescription',
x0018003a: 'InterventionDescription',
x00180040: 'CineRate',
x00180042: 'InitialCineRunState',
x00180050: 'SliceThickness',
x00180060: 'KVP',
x00180070: 'CountsAccumulated',
x00180071: 'AcquisitionTerminationCondition',
x00180072: 'EffectiveDuration',
x00180073: 'AcquisitionStartCondition',
x00180074: 'AcquisitionStartConditionData',
x00180075: 'AcquisitionEndConditionData',
x00180080: 'RepetitionTime',
x00180081: 'EchoTime',
x00180082: 'InversionTime',
x00180083: 'NumberOfAverages',
x00180084: 'ImagingFrequency',
x00180085: 'ImagedNucleus',
x00180086: 'EchoNumber',
x00180087: 'MagneticFieldStrength',
x00180088: 'SpacingBetweenSlices',
x00180089: 'NumberOfPhaseEncodingSteps',
x00180090: 'DataCollectionDiameter',
x00180091: 'EchoTrainLength',
x00180093: 'PercentSampling',
x00180094: 'PercentPhaseFieldOfView',
x00180095: 'PixelBandwidth',
x00181000: 'DeviceSerialNumber',
x00181002: 'DeviceUID',
x00181003: 'DeviceID',
x00181004: 'PlateID',
x00181005: 'GeneratorID',
x00181006: 'GridID',
x00181007: 'CassetteID',
x00181008: 'GantryID',
x00181010: 'SecondaryCaptureDeviceID',
x00181011: 'HardcopyCreationDeviceID',
x00181012: 'DateOfSecondaryCapture',
x00181014: 'TimeOfSecondaryCapture',
x00181016: 'SecondaryCaptureDeviceManufacturer',
x00181017: 'HardcopyDeviceManufacturer',
x00181018: 'SecondaryCaptureDeviceModelName',
x00181019: 'SecondaryCaptureDeviceSoftwareVers',
x0018101a: 'HardcopyDeviceSoftwareVersion',
x0018101b: 'HardcopyDeviceModelName',
x00181020: 'SoftwareVersion',
x00181022: 'VideoImageFormatAcquired',
x00181023: 'DigitalImageFormatAcquired',
x00181030: 'ProtocolName',
x00181040: 'ContrastBolusRoute',
x00181041: 'ContrastBolusVolume',
x00181042: 'ContrastBolusStartTime',
x00181043: 'ContrastBolusStopTime',
x00181044: 'ContrastBolusTotalDose',
x00181045: 'SyringeCounts',
x00181046: 'ContrastFlowRate',
x00181047: 'ContrastFlowDuration',
x00181048: 'ContrastBolusIngredient',
x00181049: 'ContrastBolusConcentration',
x00181050: 'SpatialResolution',
x00181060: 'TriggerTime',
x00181061: 'TriggerSourceOrType',
x00181062: 'NominalInterval',
x00181063: 'FrameTime',
x00181064: 'CardiacFramingType',
x00181065: 'FrameTimeVector',
x00181066: 'FrameDelay',
x00181067: 'ImageTriggerDelay',
x00181068: 'MultiplexGroupTimeOffset',
x00181069: 'TriggerTimeOffset',
x0018106a: 'SynchronizationTrigger',
x0018106c: 'SynchronizationChannel',
x0018106e: 'TriggerSamplePosition',
x00181070: 'RadiopharmaceuticalRoute',
x00181071: 'RadiopharmaceuticalVolume',
x00181072: 'RadiopharmaceuticalStartTime',
x00181073: 'RadiopharmaceuticalStopTime',
x00181074: 'RadionuclideTotalDose',
x00181075: 'RadionuclideHalfLife',
x00181076: 'RadionuclidePositronFraction',
x00181077: 'RadiopharmaceuticalSpecActivity',
x00181078: 'RadiopharmaceuticalStartDateTime',
x00181079: 'RadiopharmaceuticalStopDateTime',
x00181080: 'BeatRejectionFlag',
x00181081: 'LowRRValue',
x00181082: 'HighRRValue',
x00181083: 'IntervalsAcquired',
x00181084: 'IntervalsRejected',
x00181085: 'PVCRejection',
x00181086: 'SkipBeats',
x00181088: 'HeartRate',
x00181090: 'CardiacNumberOfImages',
x00181094: 'TriggerWindow',
x00181100: 'ReconstructionDiameter',
x00181110: 'DistanceSourceToDetector',
x00181111: 'DistanceSourceToPatient',
x00181114: 'EstimatedRadiographicMagnification',
x00181120: 'GantryDetectorTilt',
x00181121: 'GantryDetectorSlew',
x00181130: 'TableHeight',
x00181131: 'TableTraverse',
x00181134: 'TableMotion',
x00181135: 'TableVerticalIncrement',
x00181136: 'TableLateralIncrement',
x00181137: 'TableLongitudinalIncrement',
x00181138: 'TableAngle',
x0018113a: 'TableType',
x00181140: 'RotationDirection',
x00181141: 'AngularPosition',
x00181142: 'RadialPosition',
x00181143: 'ScanArc',
x00181144: 'AngularStep',
x00181145: 'CenterOfRotationOffset',
x00181146: 'RotationOffset',
x00181147: 'FieldOfViewShape',
x00181149: 'FieldOfViewDimensions',
x00181150: 'ExposureTime',
x00181151: 'XRayTubeCurrent',
x00181152: 'Exposure',
x00181153: 'ExposureInMicroAmpSec',
x00181154: 'AveragePulseWidth',
x00181155: 'RadiationSetting',
x00181156: 'RectificationType',
x0018115a: 'RadiationMode',
x0018115e: 'ImageAreaDoseProduct',
x00181160: 'FilterType',
x00181161: 'TypeOfFilters',
x00181162: 'IntensifierSize',
x00181164: 'ImagerPixelSpacing',
x00181166: 'Grid',
x00181170: 'GeneratorPower',
x00181180: 'CollimatorGridName',
x00181181: 'CollimatorType',
x00181182: 'FocalDistance',
x00181183: 'XFocusCenter',
x00181184: 'YFocusCenter',
x00181190: 'FocalSpots',
x00181191: 'AnodeTargetMaterial',
x001811a0: 'BodyPartThickness',
x001811a2: 'CompressionForce',
x00181200: 'DateOfLastCalibration',
x00181201: 'TimeOfLastCalibration',
x00181210: 'ConvolutionKernel',
x00181240: 'UpperLowerPixelValues',
x00181242: 'ActualFrameDuration',
x00181243: 'CountRate',
x00181244: 'PreferredPlaybackSequencing',
x00181250: 'ReceiveCoilName',
x00181251: 'TransmitCoilName',
x00181260: 'PlateType',
x00181261: 'PhosphorType',
x00181300: 'ScanVelocity',
x00181301: 'WholeBodyTechnique',
x00181302: 'ScanLength',
x00181310: 'AcquisitionMatrix',
x00181312: 'InPlanePhaseEncodingDirection',
x00181314: 'FlipAngle',
x00181315: 'VariableFlipAngleFlag',
x00181316: 'SAR',
x00181318: 'DB-Dt',
x00181400: 'AcquisitionDeviceProcessingDescr',
x00181401: 'AcquisitionDeviceProcessingCode',
x00181402: 'CassetteOrientation',
x00181403: 'CassetteSize',
x00181404: 'ExposuresOnPlate',
x00181405: 'RelativeXRayExposure',
x00181450: 'ColumnAngulation',
x00181460: 'TomoLayerHeight',
x00181470: 'TomoAngle',
x00181480: 'TomoTime',
x00181490: 'TomoType',
x00181491: 'TomoClass',
x00181495: 'NumberOfTomosynthesisSourceImages',
x00181500: 'PositionerMotion',
x00181508: 'PositionerType',
x00181510: 'PositionerPrimaryAngle',
x00181511: 'PositionerSecondaryAngle',
x00181520: 'PositionerPrimaryAngleIncrement',
x00181521: 'PositionerSecondaryAngleIncrement',
x00181530: 'DetectorPrimaryAngle',
x00181531: 'DetectorSecondaryAngle',
x00181600: 'ShutterShape',
x00181602: 'ShutterLeftVerticalEdge',
x00181604: 'ShutterRightVerticalEdge',
x00181606: 'ShutterUpperHorizontalEdge',
x00181608: 'ShutterLowerHorizontalEdge',
x00181610: 'CenterOfCircularShutter',
x00181612: 'RadiusOfCircularShutter',
x00181620: 'VerticesOfPolygonalShutter',
x00181622: 'ShutterPresentationValue',
x00181623: 'ShutterOverlayGroup',
x00181624: 'ShutterPresentationColorCIELabVal',
x00181700: 'CollimatorShape',
x00181702: 'CollimatorLeftVerticalEdge',
x00181704: 'CollimatorRightVerticalEdge',
x00181706: 'CollimatorUpperHorizontalEdge',
x00181708: 'CollimatorLowerHorizontalEdge',
x00181710: 'CenterOfCircularCollimator',
x00181712: 'RadiusOfCircularCollimator',
x00181720: 'VerticesOfPolygonalCollimator',
x00181800: 'AcquisitionTimeSynchronized',
x00181801: 'TimeSource',
x00181802: 'TimeDistributionProtocol',
x00181803: 'NTPSourceAddress',
x00182001: 'PageNumberVector',
x00182002: 'FrameLabelVector',
x00182003: 'FramePrimaryAngleVector',
x00182004: 'FrameSecondaryAngleVector',
x00182005: 'SliceLocationVector',
x00182006: 'DisplayWindowLabelVector',
x00182010: 'NominalScannedPixelSpacing',
x00182020: 'DigitizingDeviceTransportDirection',
x00182030: 'RotationOfScannedFilm',
x00183100: 'IVUSAcquisition',
x00183101: 'IVUSPullbackRate',
x00183102: 'IVUSGatedRate',
x00183103: 'IVUSPullbackStartFrameNumber',
x00183104: 'IVUSPullbackStopFrameNumber',
x00183105: 'LesionNumber',
x00184000: 'AcquisitionComments',
x00185000: 'OutputPower',
x00185010: 'TransducerData',
x00185012: 'FocusDepth',
x00185020: 'ProcessingFunction',
x00185021: 'PostprocessingFunction',
x00185022: 'MechanicalIndex',
x00185024: 'BoneThermalIndex',
x00185026: 'CranialThermalIndex',
x00185027: 'SoftTissueThermalIndex',
x00185028: 'SoftTissueFocusThermalIndex',
x00185029: 'SoftTissueSurfaceThermalIndex',
x00185030: 'DynamicRange',
x00185040: 'TotalGain',
x00185050: 'DepthOfScanField',
x00185100: 'PatientPosition',
x00185101: 'ViewPosition',
x00185104: 'ProjectionEponymousNameCodeSeq',
x00185210: 'ImageTransformationMatrix',
x00185212: 'ImageTranslationVector',
x00186000: 'Sensitivity',
x00186011: 'SequenceOfUltrasoundRegions',
x00186012: 'RegionSpatialFormat',
x00186014: 'RegionDataType',
x00186016: 'RegionFlags',
x00186018: 'RegionLocationMinX0',
x0018601a: 'RegionLocationMinY0',
x0018601c: 'RegionLocationMaxX1',
x0018601e: 'RegionLocationMaxY1',
x00186020: 'ReferencePixelX0',
x00186022: 'ReferencePixelY0',
x00186024: 'PhysicalUnitsXDirection',
x00186026: 'PhysicalUnitsYDirection',
x00186028: 'ReferencePixelPhysicalValueX',
x0018602a: 'ReferencePixelPhysicalValueY',
x0018602c: 'PhysicalDeltaX',
x0018602e: 'PhysicalDeltaY',
x00186030: 'TransducerFrequency',
x00186031: 'TransducerType',
x00186032: 'PulseRepetitionFrequency',
x00186034: 'DopplerCorrectionAngle',
x00186036: 'SteeringAngle',
x00186038: 'DopplerSampleVolumeXPosRetired',
x00186039: 'DopplerSampleVolumeXPosition',
x0018603a: 'DopplerSampleVolumeYPosRetired',
x0018603b: 'DopplerSampleVolumeYPosition',
x0018603c: 'TMLinePositionX0Retired',
x0018603d: 'TMLinePositionX0',
x0018603e: 'TMLinePositionY0Retired',
x0018603f: 'TMLinePositionY0',
x00186040: 'TMLinePositionX1Retired',
x00186041: 'TMLinePositionX1',
x00186042: 'TMLinePositionY1Retired',
x00186043: 'TMLinePositionY1',
x00186044: 'PixelComponentOrganization',
x00186046: 'PixelComponentMask',
x00186048: 'PixelComponentRangeStart',
x0018604a: 'PixelComponentRangeStop',
x0018604c: 'PixelComponentPhysicalUnits',
x0018604e: 'PixelComponentDataType',
x00186050: 'NumberOfTableBreakPoints',
x00186052: 'TableOfXBreakPoints',
x00186054: 'TableOfYBreakPoints',
x00186056: 'NumberOfTableEntries',
x00186058: 'TableOfPixelValues',
x0018605a: 'TableOfParameterValues',
x00186060: 'RWaveTimeVector',
x00187000: 'DetectorConditionsNominalFlag',
x00187001: 'DetectorTemperature',
x00187004: 'DetectorType',
x00187005: 'DetectorConfiguration',
x00187006: 'DetectorDescription',
x00187008: 'DetectorMode',
x0018700a: 'DetectorID',
x0018700c: 'DateOfLastDetectorCalibration',
x0018700e: 'TimeOfLastDetectorCalibration',
x00187010: 'DetectorExposuresSinceCalibration',
x00187011: 'DetectorExposuresSinceManufactured',
x00187012: 'DetectorTimeSinceLastExposure',
x00187014: 'DetectorActiveTime',
x00187016: 'DetectorActiveOffsetFromExposure',
x0018701a: 'DetectorBinning',
x00187020: 'DetectorElementPhysicalSize',
x00187022: 'DetectorElementSpacing',
x00187024: 'DetectorActiveShape',
x00187026: 'DetectorActiveDimensions',
x00187028: 'DetectorActiveOrigin',
x0018702a: 'DetectorManufacturerName',
x0018702b: 'DetectorManufacturersModelName',
x00187030: 'FieldOfViewOrigin',
x00187032: 'FieldOfViewRotation',
x00187034: 'FieldOfViewHorizontalFlip',
x00187040: 'GridAbsorbingMaterial',
x00187041: 'GridSpacingMaterial',
x00187042: 'GridThickness',
x00187044: 'GridPitch',
x00187046: 'GridAspectRatio',
x00187048: 'GridPeriod',
x0018704c: 'GridFocalDistance',
x00187050: 'FilterMaterial',
x00187052: 'FilterThicknessMinimum',
x00187054: 'FilterThicknessMaximum',
x00187060: 'ExposureControlMode',
x00187062: 'ExposureControlModeDescription',
x00187064: 'ExposureStatus',
x00187065: 'PhototimerSetting',
x00188150: 'ExposureTimeInMicroSec',
x00188151: 'XRayTubeCurrentInMicroAmps',
x00189004: 'ContentQualification',
x00189005: 'PulseSequenceName',
x00189006: 'MRImagingModifierSequence',
x00189008: 'EchoPulseSequence',
x00189009: 'InversionRecovery',
x00189010: 'FlowCompensation',
x00189011: 'MultipleSpinEcho',
x00189012: 'MultiPlanarExcitation',
x00189014: 'PhaseContrast',
x00189015: 'TimeOfFlightContrast',
x00189016: 'Spoiling',
x00189017: 'SteadyStatePulseSequence',
x00189018: 'EchoPlanarPulseSequence',
x00189019: 'TagAngleFirstAxis',
x00189020: 'MagnetizationTransfer',
x00189021: 'T2Preparation',
x00189022: 'BloodSignalNulling',
x00189024: 'SaturationRecovery',
x00189025: 'SpectrallySelectedSuppression',
x00189026: 'SpectrallySelectedExcitation',
x00189027: 'SpatialPresaturation',
x00189028: 'Tagging',
x00189029: 'OversamplingPhase',
x00189030: 'TagSpacingFirstDimension',
x00189032: 'GeometryOfKSpaceTraversal',
x00189033: 'SegmentedKSpaceTraversal',
x00189034: 'RectilinearPhaseEncodeReordering',
x00189035: 'TagThickness',
x00189036: 'PartialFourierDirection',
x00189037: 'CardiacSynchronizationTechnique',
x00189041: 'ReceiveCoilManufacturerName',
x00189042: 'MRReceiveCoilSequence',
x00189043: 'ReceiveCoilType',
x00189044: 'QuadratureReceiveCoil',
x00189045: 'MultiCoilDefinitionSequence',
x00189046: 'MultiCoilConfiguration',
x00189047: 'MultiCoilElementName',
x00189048: 'MultiCoilElementUsed',
x00189049: 'MRTransmitCoilSequence',
x00189050: 'TransmitCoilManufacturerName',
x00189051: 'TransmitCoilType',
x00189052: 'SpectralWidth',
x00189053: 'ChemicalShiftReference',
x00189054: 'VolumeLocalizationTechnique',
x00189058: 'MRAcquisitionFrequencyEncodeSteps',
x00189059: 'Decoupling',
x00189060: 'DecoupledNucleus',
x00189061: 'DecouplingFrequency',
x00189062: 'DecouplingMethod',
x00189063: 'DecouplingChemicalShiftReference',
x00189064: 'KSpaceFiltering',
x00189065: 'TimeDomainFiltering',
x00189066: 'NumberOfZeroFills',
x00189067: 'BaselineCorrection',
x00189069: 'ParallelReductionFactorInPlane',
x00189070: 'CardiacRRIntervalSpecified',
x00189073: 'AcquisitionDuration',
x00189074: 'FrameAcquisitionDateTime',
x00189075: 'DiffusionDirectionality',
x00189076: 'DiffusionGradientDirectionSequence',
x00189077: 'ParallelAcquisition',
x00189078: 'ParallelAcquisitionTechnique',
x00189079: 'InversionTimes',
x00189080: 'MetaboliteMapDescription',
x00189081: 'PartialFourier',
x00189082: 'EffectiveEchoTime',
x00189083: 'MetaboliteMapCodeSequence',
x00189084: 'ChemicalShiftSequence',
x00189085: 'CardiacSignalSource',
x00189087: 'DiffusionBValue',
x00189089: 'DiffusionGradientOrientation',
x00189090: 'VelocityEncodingDirection',
x00189091: 'VelocityEncodingMinimumValue',
x00189093: 'NumberOfKSpaceTrajectories',
x00189094: 'CoverageOfKSpace',
x00189095: 'SpectroscopyAcquisitionPhaseRows',
x00189096: 'ParallelReductFactorInPlaneRetired',
x00189098: 'TransmitterFrequency',
x00189100: 'ResonantNucleus',
x00189101: 'FrequencyCorrection',
x00189103: 'MRSpectroscopyFOV-GeometrySequence',
x00189104: 'SlabThickness',
x00189105: 'SlabOrientation',
x00189106: 'MidSlabPosition',
x00189107: 'MRSpatialSaturationSequence',
x00189112: 'MRTimingAndRelatedParametersSeq',
x00189114: 'MREchoSequence',
x00189115: 'MRModifierSequence',
x00189117: 'MRDiffusionSequence',
x00189118: 'CardiacTriggerSequence',
x00189119: 'MRAveragesSequence',
x00189125: 'MRFOV-GeometrySequence',
x00189126: 'VolumeLocalizationSequence',
x00189127: 'SpectroscopyAcquisitionDataColumns',
x00189147: 'DiffusionAnisotropyType',
x00189151: 'FrameReferenceDateTime',
x00189152: 'MRMetaboliteMapSequence',
x00189155: 'ParallelReductionFactorOutOfPlane',
x00189159: 'SpectroscopyOutOfPlanePhaseSteps',
x00189166: 'BulkMotionStatus',
x00189168: 'ParallelReductionFactSecondInPlane',
x00189169: 'CardiacBeatRejectionTechnique',
x00189170: 'RespiratoryMotionCompTechnique',
x00189171: 'RespiratorySignalSource',
x00189172: 'BulkMotionCompensationTechnique',
x00189173: 'BulkMotionSignalSource',
x00189174: 'ApplicableSafetyStandardAgency',
x00189175: 'ApplicableSafetyStandardDescr',
x00189176: 'OperatingModeSequence',
x00189177: 'OperatingModeType',
x00189178: 'OperatingMode',
x00189179: 'SpecificAbsorptionRateDefinition',
x00189180: 'GradientOutputType',
x00189181: 'SpecificAbsorptionRateValue',
x00189182: 'GradientOutput',
x00189183: 'FlowCompensationDirection',
x00189184: 'TaggingDelay',
x00189185: 'RespiratoryMotionCompTechDescr',
x00189186: 'RespiratorySignalSourceID',
x00189195: 'ChemicalShiftsMinIntegrateLimitHz',
x00189196: 'ChemicalShiftsMaxIntegrateLimitHz',
x00189197: 'MRVelocityEncodingSequence',
x00189198: 'FirstOrderPhaseCorrection',
x00189199: 'WaterReferencedPhaseCorrection',
x00189200: 'MRSpectroscopyAcquisitionType',
x00189214: 'RespiratoryCyclePosition',
x00189217: 'VelocityEncodingMaximumValue',
x00189218: 'TagSpacingSecondDimension',
x00189219: 'TagAngleSecondAxis',
x00189220: 'FrameAcquisitionDuration',
x00189226: 'MRImageFrameTypeSequence',
x00189227: 'MRSpectroscopyFrameTypeSequence',
x00189231: 'MRAcqPhaseEncodingStepsInPlane',
x00189232: 'MRAcqPhaseEncodingStepsOutOfPlane',
x00189234: 'SpectroscopyAcqPhaseColumns',
x00189236: 'CardiacCyclePosition',
x00189239: 'SpecificAbsorptionRateSequence',
x00189240: 'RFEchoTrainLength',
x00189241: 'GradientEchoTrainLength',
x00189295: 'ChemicalShiftsMinIntegrateLimitPPM',
x00189296: 'ChemicalShiftsMaxIntegrateLimitPPM',
x00189301: 'CTAcquisitionTypeSequence',
x00189302: 'AcquisitionType',
x00189303: 'TubeAngle',
x00189304: 'CTAcquisitionDetailsSequence',
x00189305: 'RevolutionTime',
x00189306: 'SingleCollimationWidth',
x00189307: 'TotalCollimationWidth',
x00189308: 'CTTableDynamicsSequence',
x00189309: 'TableSpeed',
x00189310: 'TableFeedPerRotation',
x00189311: 'SpiralPitchFactor',
x00189312: 'CTGeometrySequence',
x00189313: 'DataCollectionCenterPatient',
x00189314: 'CTReconstructionSequence',
x00189315: 'ReconstructionAlgorithm',
x00189316: 'ConvolutionKernelGroup',
x00189317: 'ReconstructionFieldOfView',
x00189318: 'ReconstructionTargetCenterPatient',
x00189319: 'ReconstructionAngle',
x00189320: 'ImageFilter',
x00189321: 'CTExposureSequence',
x00189322: 'ReconstructionPixelSpacing',
x00189323: 'ExposureModulationType',
x00189324: 'EstimatedDoseSaving',
x00189325: 'CTXRayDetailsSequence',
x00189326: 'CTPositionSequence',
x00189327: 'TablePosition',
x00189328: 'ExposureTimeInMilliSec',
x00189329: 'CTImageFrameTypeSequence',
x00189330: 'XRayTubeCurrentInMilliAmps',
x00189332: 'ExposureInMilliAmpSec',
x00189333: 'ConstantVolumeFlag',
x00189334: 'FluoroscopyFlag',
x00189335: 'SourceToDataCollectionCenterDist',
x00189337: 'ContrastBolusAgentNumber',
x00189338: 'ContrastBolusIngredientCodeSeq',
x00189340: 'ContrastAdministrationProfileSeq',
x00189341: 'ContrastBolusUsageSequence',
x00189342: 'ContrastBolusAgentAdministered',
x00189343: 'ContrastBolusAgentDetected',
x00189344: 'ContrastBolusAgentPhase',
x00189345: 'CTDIvol',
x00189346: 'CTDIPhantomTypeCodeSequence',
x00189351: 'CalciumScoringMassFactorPatient',
x00189352: 'CalciumScoringMassFactorDevice',
x00189353: 'EnergyWeightingFactor',
x00189360: 'CTAdditionalXRaySourceSequence',
x00189401: 'ProjectionPixelCalibrationSequence',
x00189402: 'DistanceSourceToIsocenter',
x00189403: 'DistanceObjectToTableTop',
x00189404: 'ObjectPixelSpacingInCenterOfBeam',
x00189405: 'PositionerPositionSequence',
x00189406: 'TablePositionSequence',
x00189407: 'CollimatorShapeSequence',
x00189412: 'XA-XRFFrameCharacteristicsSequence',
x00189417: 'FrameAcquisitionSequence',
x00189420: 'XRayReceptorType',
x00189423: 'AcquisitionProtocolName',
x00189424: 'AcquisitionProtocolDescription',
x00189425: 'ContrastBolusIngredientOpaque',
x00189426: 'DistanceReceptorPlaneToDetHousing',
x00189427: 'IntensifierActiveShape',
x00189428: 'IntensifierActiveDimensions',
x00189429: 'PhysicalDetectorSize',
x00189430: 'PositionOfIsocenterProjection',
x00189432: 'FieldOfViewSequence',
x00189433: 'FieldOfViewDescription',
x00189434: 'ExposureControlSensingRegionsSeq',
x00189435: 'ExposureControlSensingRegionShape',
x00189436: 'ExposureControlSensRegionLeftEdge',
x00189437: 'ExposureControlSensRegionRightEdge',
x00189440: 'CenterOfCircExposControlSensRegion',
x00189441: 'RadiusOfCircExposControlSensRegion',
x00189447: 'ColumnAngulationPatient',
x00189449: 'BeamAngle',
x00189451: 'FrameDetectorParametersSequence',
x00189452: 'CalculatedAnatomyThickness',
x00189455: 'CalibrationSequence',
x00189456: 'ObjectThicknessSequence',
x00189457: 'PlaneIdentification',
x00189461: 'FieldOfViewDimensionsInFloat',
x00189462: 'IsocenterReferenceSystemSequence',
x00189463: 'PositionerIsocenterPrimaryAngle',
x00189464: 'PositionerIsocenterSecondaryAngle',
x00189465: 'PositionerIsocenterDetRotAngle',
x00189466: 'TableXPositionToIsocenter',
x00189467: 'TableYPositionToIsocenter',
x00189468: 'TableZPositionToIsocenter',
x00189469: 'TableHorizontalRotationAngle',
x00189470: 'TableHeadTiltAngle',
x00189471: 'TableCradleTiltAngle',
x00189472: 'FrameDisplayShutterSequence',
x00189473: 'AcquiredImageAreaDoseProduct',
x00189474: 'CArmPositionerTabletopRelationship',
x00189476: 'XRayGeometrySequence',
x00189477: 'IrradiationEventIDSequence',
x00189504: 'XRay3DFrameTypeSequence',
x00189506: 'ContributingSourcesSequence',
x00189507: 'XRay3DAcquisitionSequence',
x00189508: 'PrimaryPositionerScanArc',
x00189509: 'SecondaryPositionerScanArc',
x00189510: 'PrimaryPositionerScanStartAngle',
x00189511: 'SecondaryPositionerScanStartAngle',
x00189514: 'PrimaryPositionerIncrement',
x00189515: 'SecondaryPositionerIncrement',
x00189516: 'StartAcquisitionDateTime',
x00189517: 'EndAcquisitionDateTime',
x00189524: 'ApplicationName',
x00189525: 'ApplicationVersion',
x00189526: 'ApplicationManufacturer',
x00189527: 'AlgorithmType',
x00189528: 'AlgorithmDescription',
x00189530: 'XRay3DReconstructionSequence',
x00189531: 'ReconstructionDescription',
x00189538: 'PerProjectionAcquisitionSequence',
x00189601: 'DiffusionBMatrixSequence',
x00189602: 'DiffusionBValueXX',
x00189603: 'DiffusionBValueXY',
x00189604: 'DiffusionBValueXZ',
x00189605: 'DiffusionBValueYY',
x00189606: 'DiffusionBValueYZ',
x00189607: 'DiffusionBValueZZ',
x00189701: 'DecayCorrectionDateTime',
x00189715: 'StartDensityThreshold',
x00189722: 'TerminationTimeThreshold',
x00189725: 'DetectorGeometry',
x00189727: 'AxialDetectorDimension',
x00189735: 'PETPositionSequence',
x00189739: 'NumberOfIterations',
x00189740: 'NumberOfSubsets',
x00189751: 'PETFrameTypeSequence',
x00189756: 'ReconstructionType',
x00189758: 'DecayCorrected',
x00189759: 'AttenuationCorrected',
x00189760: 'ScatterCorrected',
x00189761: 'DeadTimeCorrected',
x00189762: 'GantryMotionCorrected',
x00189763: 'PatientMotionCorrected',
x00189765: 'RandomsCorrected',
x00189767: 'SensitivityCalibrated',
x00189801: 'DepthsOfFocus',
x00189804: 'ExclusionStartDatetime',
x00189805: 'ExclusionDuration',
x00189807: 'ImageDataTypeSequence',
x00189808: 'DataType',
x0018980b: 'AliasedDataType',
x0018a001: 'ContributingEquipmentSequence',
x0018a002: 'ContributionDateTime',
x0018a003: 'ContributionDescription',
// x00191002: 'NumberOfCellsIInDetector',
// x00191003: 'CellNumberAtTheta',
// x00191004: 'CellSpacing',
// x0019100f: 'HorizFrameOfRef',
// x00191011: 'SeriesContrast',
// x00191012: 'LastPseq',
// x00191013: 'StartNumberForBaseline',
// x00191014: 'EndNumberForBaseline',
// x00191015: 'StartNumberForEnhancedScans',
// x00191016: 'EndNumberForEnhancedScans',
// x00191017: 'SeriesPlane',
// x00191018: 'FirstScanRas',
// x00191019: 'FirstScanLocation',
// x0019101a: 'LastScanRas',
// x0019101b: 'LastScanLoc',
// x0019101e: 'DisplayFieldOfView',
// x00191023: 'TableSpeed',
// x00191024: 'MidScanTime',
// x00191025: 'MidScanFlag',
// x00191026: 'DegreesOfAzimuth',
// x00191027: 'GantryPeriod',
// x0019102a: 'XRayOnPosition',
// x0019102b: 'XRayOffPosition',
// x0019102c: 'NumberOfTriggers',
// x0019102e: 'AngleOfFirstView',
// x0019102f: 'TriggerFrequency',
// x00191039: 'ScanFOVType',
// x00191040: 'StatReconFlag',
// x00191041: 'ComputeType',
// x00191042: 'SegmentNumber',
// x00191043: 'TotalSegmentsRequested',
// x00191044: 'InterscanDelay',
// x00191047: 'ViewCompressionFactor',
// x0019104a: 'TotalNoOfRefChannels',
// x0019104b: 'DataSizeForScanData',
// x00191052: 'ReconPostProcflag',
// x00191057: 'CTWaterNumber',
// x00191058: 'CTBoneNumber',
// x0019105a: 'AcquisitionDuration',
// x0019105e: 'NumberOfChannels',
// x0019105f: 'IncrementBetweenChannels',
// x00191060: 'StartingView',
// x00191061: 'NumberOfViews',
// x00191062: 'IncrementBetweenViews',
// x0019106a: 'DependantOnNoViewsProcessed',
// x0019106b: 'FieldOfViewInDetectorCells',
// x00191070: 'ValueOfBackProjectionButton',
// x00191071: 'SetIfFatqEstimatesWereUsed',
// x00191072: 'ZChanAvgOverViews',
// x00191073: 'AvgOfLeftRefChansOverViews',
// x00191074: 'MaxLeftChanOverViews',
// x00191075: 'AvgOfRightRefChansOverViews',
// x00191076: 'MaxRightChanOverViews',
// x0019107d: 'SecondEcho',
// x0019107e: 'NumberOfEchoes',
// x0019107f: 'TableDelta',
// x00191081: 'Contiguous',
// x00191084: 'PeakSAR',
// x00191085: 'MonitorSAR',
// x00191087: 'CardiacRepetitionTime',
// x00191088: 'ImagesPerCardiacCycle',
// x0019108a: 'ActualReceiveGainAnalog',
// x0019108b: 'ActualReceiveGainDigital',
// x0019108d: 'DelayAfterTrigger',
// x0019108f: 'Swappf',
// x00191090: 'PauseInterval',
// x00191091: 'PulseTime',
// x00191092: 'SliceOffsetOnFreqAxis',
// x00191093: 'CenterFrequency',
// x00191094: 'TransmitGain',
// x00191095: 'AnalogReceiverGain',
// x00191096: 'DigitalReceiverGain',
// x00191097: 'BitmapDefiningCVs',
// x00191098: 'CenterFreqMethod',
// x0019109b: 'PulseSeqMode',
// x0019109c: 'PulseSeqName',
// x0019109d: 'PulseSeqDate',
// x0019109e: 'InternalPulseSeqName',
// x0019109f: 'TransmittingCoil',
// x001910a0: 'SurfaceCoilType',
// x001910a1: 'ExtremityCoilFlag',
// x001910a2: 'RawDataRunNumber',
// x001910a3: 'CalibratedFieldStrength',
// x001910a4: 'SATFatWaterBone',
// x001910a5: 'ReceiveBandwidth',
// x001910a7: 'UserData01',
// x001910a8: 'UserData02',
// x001910a9: 'UserData03',
// x001910aa: 'UserData04',
// x001910ab: 'UserData05',
// x001910ac: 'UserData06',
// x001910ad: 'UserData07',
// x001910ae: 'UserData08',
// x001910af: 'UserData09',
// x001910b0: 'UserData10',
// x001910b1: 'UserData11',
// x001910b2: 'UserData12',
// x001910b3: 'UserData13',
// x001910b4: 'UserData14',
// x001910b5: 'UserData15',
// x001910b6: 'UserData16',
// x001910b7: 'UserData17',
// x001910b8: 'UserData18',
// x001910b9: 'UserData19',
// x001910ba: 'UserData20',
// x001910bb: 'UserData21',
// x001910bc: 'UserData22',
// x001910bd: 'UserData23',
// x001910be: 'ProjectionAngle',
// x001910c0: 'SaturationPlanes',
// x001910c1: 'SurfaceCoilIntensity',
// x001910c2: 'SATLocationR',
// x001910c3: 'SATLocationL',
// x001910c4: 'SATLocationA',
// x001910c5: 'SATLocationP',
// x001910c6: 'SATLocationH',
// x001910c7: 'SATLocationF',
// x001910c8: 'SATThicknessR-L',
// x001910c9: 'SATThicknessA-P',
// x001910ca: 'SATThicknessH-F',
// x001910cb: 'PrescribedFlowAxis',
// x001910cc: 'VelocityEncoding',
// x001910cd: 'ThicknessDisclaimer',
// x001910ce: 'PrescanType',
// x001910cf: 'PrescanStatus',
// x001910d0: 'RawDataType',
// x001910d2: 'ProjectionAlgorithm',
// x001910d3: 'ProjectionAlgorithm',
// x001910d5: 'FractionalEcho',
// x001910d6: 'PrepPulse',
// x001910d7: 'CardiacPhases',
// x001910d8: 'VariableEchoflag',
// x001910d9: 'ConcatenatedSAT',
// x001910da: 'ReferenceChannelUsed',
// x001910db: 'BackProjectorCoefficient',
// x001910dc: 'PrimarySpeedCorrectionUsed',
// x001910dd: 'OverrangeCorrectionUsed',
// x001910de: 'DynamicZAlphaValue',
// x001910df: 'UserData',
// x001910e0: 'UserData',
// x001910e2: 'VelocityEncodeScale',
// x001910f2: 'FastPhases',
// x001910f9: 'TransmissionGain',
x00200000: 'RelationshipGroupLength',
x0020000d: 'StudyInstanceUID',
x0020000e: 'SeriesInstanceUID',
x00200010: 'StudyID',
x00200011: 'SeriesNumber',
x00200012: 'AcquisitionNumber',
x00200013: 'InstanceNumber',
x00200014: 'IsotopeNumber',
x00200015: 'PhaseNumber',
x00200016: 'IntervalNumber',
x00200017: 'TimeSlotNumber',
x00200018: 'AngleNumber',
x00200019: 'ItemNumber',
x00200020: 'PatientOrientation',
x00200022: 'OverlayNumber',
x00200024: 'CurveNumber',
x00200026: 'LookupTableNumber',
x00200030: 'ImagePosition',
x00200032: 'ImagePositionPatient',
x00200035: 'ImageOrientation',
x00200037: 'ImageOrientationPatient',
x00200050: 'Location',
x00200052: 'FrameOfReferenceUID',
x00200060: 'Laterality',
x00200062: 'ImageLaterality',
x00200070: 'ImageGeometryType',
x00200080: 'MaskingImage',
x00200100: 'TemporalPositionIdentifier',
x00200105: 'NumberOfTemporalPositions',
x00200110: 'TemporalResolution',
x00200200: 'SynchronizationFrameOfReferenceUID',
x00201000: 'SeriesInStudy',
x00201001: 'AcquisitionsInSeries',
x00201002: 'ImagesInAcquisition',
x00201003: 'ImagesInSeries',
x00201004: 'AcquisitionsInStudy',
x00201005: 'ImagesInStudy',
x00201020: 'Reference',
x00201040: 'PositionReferenceIndicator',
x00201041: 'SliceLocation',
x00201070: 'OtherStudyNumbers',
x00201200: 'NumberOfPatientRelatedStudies',
x00201202: 'NumberOfPatientRelatedSeries',
x00201204: 'NumberOfPatientRelatedInstances',
x00201206: 'NumberOfStudyRelatedSeries',
x00201208: 'NumberOfStudyRelatedInstances',
x00201209: 'NumberOfSeriesRelatedInstances',
x002031xx: 'SourceImageIDs',
x00203401: 'ModifyingDeviceID',
x00203402: 'ModifiedImageID',
x00203403: 'ModifiedImageDate',
x00203404: 'ModifyingDeviceManufacturer',
x00203405: 'ModifiedImageTime',
x00203406: 'ModifiedImageDescription',
x00204000: 'ImageComments',
x00205000: 'OriginalImageIdentification',
x00205002: 'OriginalImageIdentNomenclature',
x00209056: 'StackID',
x00209057: 'InStackPositionNumber',
x00209071: 'FrameAnatomySequence',
x00209072: 'FrameLaterality',
x00209111: 'FrameContentSequence',
x00209113: 'PlanePositionSequence',
x00209116: 'PlaneOrientationSequence',
x00209128: 'TemporalPositionIndex',
x00209153: 'TriggerDelayTime',
x00209156: 'FrameAcquisitionNumber',
x00209157: 'DimensionIndexValues',
x00209158: 'FrameComments',
x00209161: 'ConcatenationUID',
x00209162: 'InConcatenationNumber',
x00209163: 'InConcatenationTotalNumber',
x00209164: 'DimensionOrganizationUID',
x00209165: 'DimensionIndexPointer',
x00209167: 'FunctionalGroupPointer',
x00209213: 'DimensionIndexPrivateCreator',
x00209221: 'DimensionOrganizationSequence',
x00209222: 'DimensionIndexSequence',
x00209228: 'ConcatenationFrameOffsetNumber',
x00209238: 'FunctionalGroupPrivateCreator',
x00209241: 'NominalPercentageOfCardiacPhase',
x00209245: 'NominalPercentOfRespiratoryPhase',
x00209246: 'StartingRespiratoryAmplitude',
x00209247: 'StartingRespiratoryPhase',
x00209248: 'EndingRespiratoryAmplitude',
x00209249: 'EndingRespiratoryPhase',
x00209250: 'RespiratoryTriggerType',
x00209251: 'RRIntervalTimeNominal',
x00209252: 'ActualCardiacTriggerDelayTime',
x00209253: 'RespiratorySynchronizationSequence',
x00209254: 'RespiratoryIntervalTime',
x00209255: 'NominalRespiratoryTriggerDelayTime',
x00209256: 'RespiratoryTriggerDelayThreshold',
x00209257: 'ActualRespiratoryTriggerDelayTime',
x00209301: 'ImagePositionVolume',
x00209302: 'ImageOrientationVolume',
x00209308: 'ApexPosition',
x00209421: 'DimensionDescriptionLabel',
x00209450: 'PatientOrientationInFrameSequence',
x00209453: 'FrameLabel',
x00209518: 'AcquisitionIndex',
x00209529: 'ContributingSOPInstancesRefSeq',
x00209536: 'ReconstructionIndex',
// x00211003: 'SeriesFromWhichPrescribed',
// x00211005: 'GenesisVersionNow',
// x00211007: 'SeriesRecordChecksum',
// x00211018: 'GenesisVersionNow',
// x00211019: 'AcqreconRecordChecksum',
// x00211020: 'TableStartLocation',
// x00211035: 'SeriesFromWhichPrescribed',
// x00211036: 'ImageFromWhichPrescribed',
// x00211037: 'ScreenFormat',
// x0021104a: 'AnatomicalReferenceForScout',
// x0021104f: 'LocationsInAcquisition',
// x00211050: 'GraphicallyPrescribed',
// x00211051: 'RotationFromSourceXRot',
// x00211052: 'RotationFromSourceYRot',
// x00211053: 'RotationFromSourceZRot',
// x00211054: 'ImagePosition',
// x00211055: 'ImageOrientation',
// x00211056: 'IntegerSlop',
// x00211057: 'IntegerSlop',
// x00211058: 'IntegerSlop',
// x00211059: 'IntegerSlop',
// x0021105a: 'IntegerSlop',
// x0021105b: 'FloatSlop',
// x0021105c: 'FloatSlop',
// x0021105d: 'FloatSlop',
// x0021105e: 'FloatSlop',
// x0021105f: 'FloatSlop',
// x00211081: 'AutoWindowLevelAlpha',
// x00211082: 'AutoWindowLevelBeta',
// x00211083: 'AutoWindowLevelWindow',
// x00211084: 'ToWindowLevelLevel',
// x00211090: 'TubeFocalSpotPosition',
// x00211091: 'BiopsyPosition',
// x00211092: 'BiopsyTLocation',
// x00211093: 'BiopsyRefLocation',
x00220001: 'LightPathFilterPassThroughWavelen',
x00220002: 'LightPathFilterPassBand',
x00220003: 'ImagePathFilterPassThroughWavelen',
x00220004: 'ImagePathFilterPassBand',
x00220005: 'PatientEyeMovementCommanded',
x00220006: 'PatientEyeMovementCommandCodeSeq',
x00220007: 'SphericalLensPower',
x00220008: 'CylinderLensPower',
x00220009: 'CylinderAxis',
x0022000a: 'EmmetropicMagnification',
x0022000b: 'IntraOcularPressure',
x0022000c: 'HorizontalFieldOfView',
x0022000d: 'PupilDilated',
x0022000e: 'DegreeOfDilation',
x00220010: 'StereoBaselineAngle',
x00220011: 'StereoBaselineDisplacement',
x00220012: 'StereoHorizontalPixelOffset',
x00220013: 'StereoVerticalPixelOffset',
x00220014: 'StereoRotation',
x00220015: 'AcquisitionDeviceTypeCodeSequence',
x00220016: 'IlluminationTypeCodeSequence',
x00220017: 'LightPathFilterTypeStackCodeSeq',
x00220018: 'ImagePathFilterTypeStackCodeSeq',
x00220019: 'LensesCodeSequence',
x0022001a: 'ChannelDescriptionCodeSequence',
x0022001b: 'RefractiveStateSequence',
x0022001c: 'MydriaticAgentCodeSequence',
x0022001d: 'RelativeImagePositionCodeSequence',
x00220020: 'StereoPairsSequence',
x00220021: 'LeftImageSequence',
x00220022: 'RightImageSequence',
x00220030: 'AxialLengthOfTheEye',
x00220031: 'OphthalmicFrameLocationSequence',
x00220032: 'ReferenceCoordinates',
x00220035: 'DepthSpatialResolution',
x00220036: 'MaximumDepthDistortion',
x00220037: 'AlongScanSpatialResolution',
x00220038: 'MaximumAlongScanDistortion',
x00220039: 'OphthalmicImageOrientation',
x00220041: 'DepthOfTransverseImage',
x00220042: 'MydriaticAgentConcUnitsSeq',
x00220048: 'AcrossScanSpatialResolution',
x00220049: 'MaximumAcrossScanDistortion',
x0022004e: 'MydriaticAgentConcentration',
x00220055: 'IlluminationWaveLength',
x00220056: 'IlluminationPower',
x00220057: 'IlluminationBandwidth',
x00220058: 'MydriaticAgentSequence',
// x00231001: 'NumberOfSeriesInStudy',
// x00231002: 'NumberOfUnarchivedSeries',
// x00231010: 'ReferenceImageField',
// x00231050: 'SummaryImage',
// x00231070: 'StartTimeSecsInFirstAxial',
// x00231074: 'NoofUpdatesToHeader',
// x0023107d: 'IndicatesIfTheStudyHasCompleteInfo',
// x00251006: 'LastPulseSequenceUsed',
// x00251007: 'ImagesInSeries',
// x00251010: 'LandmarkCounter',
// x00251011: 'NumberOfAcquisitions',
// x00251014: 'IndicatesNoofUpdatesToHeader',
// x00251017: 'SeriesCompleteFlag',
// x00251018: 'NumberOfImagesArchived',
// x00251019: 'LastImageNumberUsed',
// x0025101a: 'PrimaryReceiverSuiteAndHost',
// x00271006: 'ImageArchiveFlag',
// x00271010: 'ScoutType',
// x0027101c: 'VmaMamp',
// x0027101d: 'VmaPhase',
// x0027101e: 'VmaMod',
// x0027101f: 'VmaClip',
// x00271020: 'SmartScanOnOffFlag',
// x00271030: 'ForeignImageRevision',
// x00271031: 'ImagingMode',
// x00271032: 'PulseSequence',
// x00271033: 'ImagingOptions',
// x00271035: 'PlaneType',
// x00271036: 'ObliquePlane',
// x00271040: 'RASLetterOfImageLocation',
// x00271041: 'ImageLocation',
// x00271042: 'CenterRCoordOfPlaneImage',
// x00271043: 'CenterACoordOfPlaneImage',
// x00271044: 'CenterSCoordOfPlaneImage',
// x00271045: 'NormalRCoord',
// x00271046: 'NormalACoord',
// x00271047: 'NormalSCoord',
// x00271048: 'RCoordOfTopRightCorner',
// x00271049: 'ACoordOfTopRightCorner',
// x0027104a: 'SCoordOfTopRightCorner',
// x0027104b: 'RCoordOfBottomRightCorner',
// x0027104c: 'ACoordOfBottomRightCorner',
// x0027104d: 'SCoordOfBottomRightCorner',
// x00271050: 'TableStartLocation',
// x00271051: 'TableEndLocation',
// x00271052: 'RASLetterForSideOfImage',
// x00271053: 'RASLetterForAnteriorPosterior',
// x00271054: 'RASLetterForScoutStartLoc',
// x00271055: 'RASLetterForScoutEndLoc',
// x00271060: 'ImageDimensionX',
// x00271061: 'ImageDimensionY',
// x00271062: 'NumberOfExcitations',
x00280000: 'ImagePresentationGroupLength',
x00280002: 'SamplesPerPixel',
x00280003: 'SamplesPerPixelUsed',
x00280004: 'PhotometricInterpretation',
x00280005: 'ImageDimensions',
x00280006: 'PlanarConfiguration',
x00280008: 'NumberOfFrames',
x00280009: 'FrameIncrementPointer',
x0028000a: 'FrameDimensionPointer',
x00280010: 'Rows',
x00280011: 'Columns',
x00280012: 'Planes',
x00280014: 'UltrasoundColorDataPresent',
x00280030: 'PixelSpacing',
x00280031: 'ZoomFactor',
x00280032: 'ZoomCenter',
x00280034: 'PixelAspectRatio',
x00280040: 'ImageFormat',
x00280050: 'ManipulatedImage',
x00280051: 'CorrectedImage',
x0028005f: 'CompressionRecognitionCode',
x00280060: 'CompressionCode',
x00280061: 'CompressionOriginator',
x00280062: 'CompressionLabel',
x00280063: 'CompressionDescription',
x00280065: 'CompressionSequence',
x00280066: 'CompressionStepPointers',
x00280068: 'RepeatInterval',
x00280069: 'BitsGrouped',
x00280070: 'PerimeterTable',
x00280071: 'PerimeterValue',
x00280080: 'PredictorRows',
x00280081: 'PredictorColumns',
x00280082: 'PredictorConstants',
x00280090: 'BlockedPixels',
x00280091: 'BlockRows',
x00280092: 'BlockColumns',
x00280093: 'RowOverlap',
x00280094: 'ColumnOverlap',
x00280100: 'BitsAllocated',
x00280101: 'BitsStored',
x00280102: 'HighBit',
x00280103: 'PixelRepresentation',
x00280104: 'SmallestValidPixelValue',
x00280105: 'LargestValidPixelValue',
x00280106: 'SmallestImagePixelValue',
x00280107: 'LargestImagePixelValue',
x00280108: 'SmallestPixelValueInSeries',
x00280109: 'LargestPixelValueInSeries',
x00280110: 'SmallestImagePixelValueInPlane',
x00280111: 'LargestImagePixelValueInPlane',
x00280120: 'PixelPaddingValue',
x00280121: 'PixelPaddingRangeLimit',
x00280200: 'ImageLocation',
x00280300: 'QualityControlImage',
x00280301: 'BurnedInAnnotation',
x00280400: 'TransformLabel',
x00280401: 'TransformVersionNumber',
x00280402: 'NumberOfTransformSteps',
x00280403: 'SequenceOfCompressedData',
x00280404: 'DetailsOfCoefficients',
x002804x2: 'CoefficientCoding',
x002804x3: 'CoefficientCodingPointers',
x00280700: 'DCTLabel',
x00280701: 'DataBlockDescription',
x00280702: 'DataBlock',
x00280710: 'NormalizationFactorFormat',
x00280720: 'ZonalMapNumberFormat',
x00280721: 'ZonalMapLocation',
x00280722: 'ZonalMapFormat',
x00280730: 'AdaptiveMapFormat',
x00280740: 'CodeNumberFormat',
x002808x0: 'CodeLabel',
x002808x2: 'NumberOfTables',
x002808x3: 'CodeTableLocation',
x002808x4: 'BitsForCodeWord',
x002808x8: 'ImageDataLocation',
x00280a02: 'PixelSpacingCalibrationType',
x00280a04: 'PixelSpacingCalibrationDescription',
x00281040: 'PixelIntensityRelationship',
x00281041: 'PixelIntensityRelationshipSign',
x00281050: 'WindowCenter',
x00281051: 'WindowWidth',
x00281052: 'RescaleIntercept',
x00281053: 'RescaleSlope',
x00281054: 'RescaleType',
x00281055: 'WindowCenterAndWidthExplanation',
x00281056: 'VOI_LUTFunction',
x00281080: 'GrayScale',
x00281090: 'RecommendedViewingMode',
x00281100: 'GrayLookupTableDescriptor',
x00281101: 'RedPaletteColorTableDescriptor',
x00281102: 'GreenPaletteColorTableDescriptor',
x00281103: 'BluePaletteColorTableDescriptor',
x00281111: 'LargeRedPaletteColorTableDescr',
x00281112: 'LargeGreenPaletteColorTableDescr',
x00281113: 'LargeBluePaletteColorTableDescr',
x00281199: 'PaletteColorTableUID',
x00281200: 'GrayLookupTableData',
x00281201: 'RedPaletteColorTableData',
x00281202: 'GreenPaletteColorTableData',
x00281203: 'BluePaletteColorTableData',
x00281211: 'LargeRedPaletteColorTableData',
x00281212: 'LargeGreenPaletteColorTableData',
x00281213: 'LargeBluePaletteColorTableData',
x00281214: 'LargePaletteColorLookupTableUID',
x00281221: 'SegmentedRedColorTableData',
x00281222: 'SegmentedGreenColorTableData',
x00281223: 'SegmentedBlueColorTableData',
x00281300: 'BreastImplantPresent',
x00281350: 'PartialView',
x00281351: 'PartialViewDescription',
x00281352: 'PartialViewCodeSequence',
x0028135a: 'SpatialLocationsPreserved',
x00281402: 'DataPathAssignment',
x00281404: 'BlendingLUT1Sequence',
x00281406: 'BlendingWeightConstant',
x00281408: 'BlendingLookupTableData',
x0028140c: 'BlendingLUT2Sequence',
x0028140e: 'DataPathID',
x0028140f: 'RGBLUTTransferFunction',
x00281410: 'AlphaLUTTransferFunction',
x00282000: 'ICCProfile',
x00282110: 'LossyImageCompression',
x00282112: 'LossyImageCompressionRatio',
x00282114: 'LossyImageCompressionMethod',
x00283000: 'ModalityLUTSequence',
x00283002: 'LUTDescriptor',
x00283003: 'LUTExplanation',
x00283004: 'ModalityLUTType',
x00283006: 'LUTData',
x00283010: 'VOILUTSequence',
x00283110: 'SoftcopyVOILUTSequence',
x00284000: 'ImagePresentationComments',
x00285000: 'BiPlaneAcquisitionSequence',
x00286010: 'RepresentativeFrameNumber',
x00286020: 'FrameNumbersOfInterest',
x00286022: 'FrameOfInterestDescription',
x00286023: 'FrameOfInterestType',
x00286030: 'MaskPointers',
x00286040: 'RWavePointer',
x00286100: 'MaskSubtractionSequence',
x00286101: 'MaskOperation',
x00286102: 'ApplicableFrameRange',
x00286110: 'MaskFrameNumbers',
x00286112: 'ContrastFrameAveraging',
x00286114: 'MaskSubPixelShift',
x00286120: 'TIDOffset',
x00286190: 'MaskOperationExplanation',
x00287fe0: 'PixelDataProviderURL',
x00289001: 'DataPointRows',
x00289002: 'DataPointColumns',
x00289003: 'SignalDomainColumns',
x00289099: 'LargestMonochromePixelValue',
x00289108: 'DataRepresentation',
x00289110: 'PixelMeasuresSequence',
x00289132: 'FrameVOILUTSequence',
x00289145: 'PixelValueTransformationSequence',
x00289235: 'SignalDomainRows',
x00289411: 'DisplayFilterPercentage',
x00289415: 'FramePixelShiftSequence',
x00289416: 'SubtractionItemID',
x00289422: 'PixelIntensityRelationshipLUTSeq',
x00289443: 'FramePixelDataPropertiesSequence',
x00289444: 'GeometricalProperties',
x00289445: 'GeometricMaximumDistortion',
x00289446: 'ImageProcessingApplied',
x00289454: 'MaskSelectionMode',
x00289474: 'LUTFunction',
x00289478: 'MaskVisibilityPercentage',
x00289501: 'PixelShiftSequence',
x00289502: 'RegionPixelShiftSequence',
x00289503: 'VerticesOfTheRegion',
x00289506: 'PixelShiftFrameRange',
x00289507: 'LUTFrameRange',
x00289520: 'ImageToEquipmentMappingMatrix',
x00289537: 'EquipmentCoordinateSystemID',
// x00291004: 'LowerRangeOfPixels1a',
// x00291005: 'LowerRangeOfPixels1b',
// x00291006: 'LowerRangeOfPixels1c',
// x00291007: 'LowerRangeOfPixels1d',
// x00291008: 'LowerRangeOfPixels1e',
// x00291009: 'LowerRangeOfPixels1f',
// x0029100a: 'LowerRangeOfPixels1g',
// x00291015: 'LowerRangeOfPixels1h',
// x00291016: 'LowerRangeOfPixels1i',
// x00291017: 'LowerRangeOfPixels2',
// x00291018: 'UpperRangeOfPixels2',
// x0029101a: 'LenOfTotHdrInBytes',
// x00291026: 'VersionOfTheHdrStruct',
// x00291034: 'AdvantageCompOverflow',
// x00291035: 'AdvantageCompUnderflow',
x00320000: 'StudyGroupLength',
x0032000a: 'StudyStatusID',
x0032000c: 'StudyPriorityID',
x00320012: 'StudyIDIssuer',
x00320032: 'StudyVerifiedDate',
x00320033: 'StudyVerifiedTime',
x00320034: 'StudyReadDate',
x00320035: 'StudyReadTime',
x00321000: 'ScheduledStudyStartDate',
x00321001: 'ScheduledStudyStartTime',
x00321010: 'ScheduledStudyStopDate',
x00321011: 'ScheduledStudyStopTime',
x00321020: 'ScheduledStudyLocation',
x00321021: 'ScheduledStudyLocationAETitle',
x00321030: 'ReasonForStudy',
x00321031: 'RequestingPhysicianIDSequence',
x00321032: 'RequestingPhysician',
x00321033: 'RequestingService',
x00321040: 'StudyArrivalDate',
x00321041: 'StudyArrivalTime',
x00321050: 'StudyCompletionDate',
x00321051: 'StudyCompletionTime',
x00321055: 'StudyComponentStatusID',
x00321060: 'RequestedProcedureDescription',
x00321064: 'RequestedProcedureCodeSequence',
x00321070: 'RequestedContrastAgent',
x00324000: 'StudyComments',
x00380004: 'ReferencedPatientAliasSequence',
x00380008: 'VisitStatusID',
x00380010: 'AdmissionID',
x00380011: 'IssuerOfAdmissionID',
x00380016: 'RouteOfAdmissions',
x0038001a: 'ScheduledAdmissionDate',
x0038001b: 'ScheduledAdmissionTime',
x0038001c: 'ScheduledDischargeDate',
x0038001d: 'ScheduledDischargeTime',
x0038001e: 'ScheduledPatientInstitResidence',
x00380020: 'AdmittingDate',
x00380021: 'AdmittingTime',
x00380030: 'DischargeDate',
x00380032: 'DischargeTime',
x00380040: 'DischargeDiagnosisDescription',
x00380044: 'DischargeDiagnosisCodeSequence',
x00380050: 'SpecialNeeds',
x00380060: 'ServiceEpisodeID',
x00380061: 'IssuerOfServiceEpisodeID',
x00380062: 'ServiceEpisodeDescription',
x00380100: 'PertinentDocumentsSequence',
x00380300: 'CurrentPatientLocation',
x00380400: 'PatientInstitutionResidence',
x00380500: 'PatientState',
x00380502: 'PatientClinicalTrialParticipSeq',
x00384000: 'VisitComments',
x003a0004: 'WaveformOriginality',
x003a0005: 'NumberOfWaveformChannels',
x003a0010: 'NumberOfWaveformSamples',
x003a001a: 'SamplingFrequency',
x003a0020: 'MultiplexGroupLabel',
x003a0200: 'ChannelDefinitionSequence',
x003a0202: 'WaveformChannelNumber',
x003a0203: 'ChannelLabel',
x003a0205: 'ChannelStatus',
x003a0208: 'ChannelSourceSequence',
x003a0209: 'ChannelSourceModifiersSequence',
x003a020a: 'SourceWaveformSequence',
x003a020c: 'ChannelDerivationDescription',
x003a0210: 'ChannelSensitivity',
x003a0211: 'ChannelSensitivityUnitsSequence',
x003a0212: 'ChannelSensitivityCorrectionFactor',
x003a0213: 'ChannelBaseline',
x003a0214: 'ChannelTimeSkew',
x003a0215: 'ChannelSampleSkew',
x003a0218: 'ChannelOffset',
x003a021a: 'WaveformBitsStored',
x003a0220: 'FilterLowFrequency',
x003a0221: 'FilterHighFrequency',
x003a0222: 'NotchFilterFrequency',
x003a0223: 'NotchFilterBandwidth',
x003a0230: 'WaveformDataDisplayScale',
x003a0231: 'WaveformDisplayBkgCIELabValue',
x003a0240: 'WaveformPresentationGroupSequence',
x003a0241: 'PresentationGroupNumber',
x003a0242: 'ChannelDisplaySequence',
x003a0244: 'ChannelRecommendDisplayCIELabValue',
x003a0245: 'ChannelPosition',
x003a0246: 'DisplayShadingFlag',
x003a0247: 'FractionalChannelDisplayScale',
x003a0248: 'AbsoluteChannelDisplayScale',
x003a0300: 'MultiplexAudioChannelsDescrCodeSeq',
x003a0301: 'ChannelIdentificationCode',
x003a0302: 'ChannelMode',
x00400001: 'ScheduledStationAETitle',
x00400002: 'ScheduledProcedureStepStartDate',
x00400003: 'ScheduledProcedureStepStartTime',
x00400004: 'ScheduledProcedureStepEndDate',
x00400005: 'ScheduledProcedureStepEndTime',
x00400006: 'ScheduledPerformingPhysiciansName',
x00400007: 'ScheduledProcedureStepDescription',
x00400008: 'ScheduledProtocolCodeSequence',
x00400009: 'ScheduledProcedureStepID',
x0040000a: 'StageCodeSequence',
x0040000b: 'ScheduledPerformingPhysicianIDSeq',
x00400010: 'ScheduledStationName',
x00400011: 'ScheduledProcedureStepLocation',
x00400012: 'PreMedication',
x00400020: 'ScheduledProcedureStepStatus',
x00400031: 'LocalNamespaceEntityID',
x00400032: 'UniversalEntityID',
x00400033: 'UniversalEntityIDType',
x00400035: 'IdentifierTypeCode',
x00400036: 'AssigningFacilitySequence',
x00400100: 'ScheduledProcedureStepSequence',
x00400220: 'ReferencedNonImageCompositeSOPSeq',
x00400241: 'PerformedStationAETitle',
x00400242: 'PerformedStationName',
x00400243: 'PerformedLocation',
x00400244: 'PerformedProcedureStepStartDate',
x00400245: 'PerformedProcedureStepStartTime',
x00400250: 'PerformedProcedureStepEndDate',
x00400251: 'PerformedProcedureStepEndTime',
x00400252: 'PerformedProcedureStepStatus',
x00400253: 'PerformedProcedureStepID',
x00400254: 'PerformedProcedureStepDescription',
x00400255: 'PerformedProcedureTypeDescription',
x00400260: 'PerformedProtocolCodeSequence',
x00400261: 'PerformedProtocolType',
x00400270: 'ScheduledStepAttributesSequence',
x00400275: 'RequestAttributesSequence',
x00400280: 'CommentsOnPerformedProcedureStep',
x00400281: 'ProcStepDiscontinueReasonCodeSeq',
x00400293: 'QuantitySequence',
x00400294: 'Quantity',
x00400295: 'MeasuringUnitsSequence',
x00400296: 'BillingItemSequence',
x00400300: 'TotalTimeOfFluoroscopy',
x00400301: 'TotalNumberOfExposures',
x00400302: 'EntranceDose',
x00400303: 'ExposedArea',
x00400306: 'DistanceSourceToEntrance',
x00400307: 'DistanceSourceToSupport',
x0040030e: 'ExposureDoseSequence',
x00400310: 'CommentsOnRadiationDose',
x00400312: 'XRayOutput',
x00400314: 'HalfValueLayer',
x00400316: 'OrganDose',
x00400318: 'OrganExposed',
x00400320: 'BillingProcedureStepSequence',
x00400321: 'FilmConsumptionSequence',
x00400324: 'BillingSuppliesAndDevicesSequence',
x00400330: 'ReferencedProcedureStepSequence',
x00400340: 'PerformedSeriesSequence',
x00400400: 'CommentsOnScheduledProcedureStep',
x00400440: 'ProtocolContextSequence',
x00400441: 'ContentItemModifierSequence',
x0040050a: 'SpecimenAccessionNumber',
x00400512: 'ContainerIdentifier',
x0040051a: 'ContainerDescription',
x00400550: 'SpecimenSequence',
x00400551: 'SpecimenIdentifier',
x00400552: 'SpecimenDescriptionSequenceTrial',
x00400553: 'SpecimenDescriptionTrial',
x00400554: 'SpecimenUID',
x00400555: 'AcquisitionContextSequence',
x00400556: 'AcquisitionContextDescription',
x0040059a: 'SpecimenTypeCodeSequence',
x00400600: 'SpecimenShortDescription',
x004006fa: 'SlideIdentifier',
x0040071a: 'ImageCenterPointCoordinatesSeq',
x0040072a: 'XOffsetInSlideCoordinateSystem',
x0040073a: 'YOffsetInSlideCoordinateSystem',
x0040074a: 'ZOffsetInSlideCoordinateSystem',
x004008d8: 'PixelSpacingSequence',
x004008da: 'CoordinateSystemAxisCodeSequence',
x004008ea: 'MeasurementUnitsCodeSequence',
x004009f8: 'VitalStainCodeSequenceTrial',
x00401001: 'RequestedProcedureID',
x00401002: 'ReasonForRequestedProcedure',
x00401003: 'RequestedProcedurePriority',
x00401004: 'PatientTransportArrangements',
x00401005: 'RequestedProcedureLocation',
x00401006: 'PlacerOrderNumber-Procedure',
x00401007: 'FillerOrderNumber-Procedure',
x00401008: 'ConfidentialityCode',
x00401009: 'ReportingPriority',
x0040100a: 'ReasonForRequestedProcedureCodeSeq',
x00401010: 'NamesOfIntendedRecipientsOfResults',
x00401011: 'IntendedRecipientsOfResultsIDSeq',
x00401101: 'PersonIdentificationCodeSequence',
x00401102: 'PersonAddress',
x00401103: 'PersonTelephoneNumbers',
x00401400: 'RequestedProcedureComments',
x00402001: 'ReasonForImagingServiceRequest',
x00402004: 'IssueDateOfImagingServiceRequest',
x00402005: 'IssueTimeOfImagingServiceRequest',
x00402006: 'PlacerOrderNumberImagingServiceRequestRetired',
x00402007: 'FillerOrderNumberImagingServiceRequestRetired',
x00402008: 'OrderEnteredBy',
x00402009: 'OrderEntererLocation',
x00402010: 'OrderCallbackPhoneNumber',
x00402016: 'PlacerOrderNum-ImagingServiceReq',
x00402017: 'FillerOrderNum-ImagingServiceReq',
x00402400: 'ImagingServiceRequestComments',
x00403001: 'ConfidentialityOnPatientDataDescr',
x00404001: 'GenPurposeScheduledProcStepStatus',
x00404002: 'GenPurposePerformedProcStepStatus',
x00404003: 'GenPurposeSchedProcStepPriority',
x00404004: 'SchedProcessingApplicationsCodeSeq',
x00404005: 'SchedProcedureStepStartDateAndTime',
x00404006: 'MultipleCopiesFlag',
x00404007: 'PerformedProcessingAppsCodeSeq',
x00404009: 'HumanPerformerCodeSequence',
x00404010: 'SchedProcStepModificationDateTime',
x00404011: 'ExpectedCompletionDateAndTime',
x00404015: 'ResultingGenPurposePerfProcStepSeq',
x00404016: 'RefGenPurposeSchedProcStepSeq',
x00404018: 'ScheduledWorkitemCodeSequence',
x00404019: 'PerformedWorkitemCodeSequence',
x00404020: 'InputAvailabilityFlag',
x00404021: 'InputInformationSequence',
x00404022: 'RelevantInformationSequence',
x00404023: 'RefGenPurSchedProcStepTransUID',
x00404025: 'ScheduledStationNameCodeSequence',
x00404026: 'ScheduledStationClassCodeSequence',
x00404027: 'SchedStationGeographicLocCodeSeq',
x00404028: 'PerformedStationNameCodeSequence',
x00404029: 'PerformedStationClassCodeSequence',
x00404030: 'PerformedStationGeogLocCodeSeq',
x00404031: 'RequestedSubsequentWorkItemCodeSeq',
x00404032: 'NonDICOMOutputCodeSequence',
x00404033: 'OutputInformationSequence',
x00404034: 'ScheduledHumanPerformersSequence',
x00404035: 'ActualHumanPerformersSequence',
x00404036: 'HumanPerformersOrganization',
x00404037: 'HumanPerformerName',
x00404040: 'RawDataHandling',
x00408302: 'EntranceDoseInMilliGy',
x00409094: 'RefImageRealWorldValueMappingSeq',
x00409096: 'RealWorldValueMappingSequence',
x00409098: 'PixelValueMappingCodeSequence',
x00409210: 'LUTLabel',
x00409211: 'RealWorldValueLastValueMapped',
x00409212: 'RealWorldValueLUTData',
x00409216: 'RealWorldValueFirstValueMapped',
x00409224: 'RealWorldValueIntercept',
x00409225: 'RealWorldValueSlope',
x0040a010: 'RelationshipType',
x0040a027: 'VerifyingOrganization',
x0040a030: 'VerificationDateTime',
x0040a032: 'ObservationDateTime',
x0040a040: 'ValueType',
x0040a043: 'ConceptNameCodeSequence',
x0040a050: 'ContinuityOfContent',
x0040a073: 'VerifyingObserverSequence',
x0040a075: 'VerifyingObserverName',
x0040a078: 'AuthorObserverSequence',
x0040a07a: 'ParticipantSequence',
x0040a07c: 'CustodialOrganizationSequence',
x0040a080: 'ParticipationType',
x0040a082: 'ParticipationDateTime',
x0040a084: 'ObserverType',
x0040a088: 'VerifyingObserverIdentCodeSequence',
x0040a090: 'EquivalentCDADocumentSequence',
x0040a0b0: 'ReferencedWaveformChannels',
x0040a120: 'DateTime',
x0040a121: 'Date',
x0040a122: 'Time',
x0040a123: 'PersonName',
x0040a124: 'UID',
x0040a130: 'TemporalRangeType',
x0040a132: 'ReferencedSamplePositions',
x0040a136: 'ReferencedFrameNumbers',
x0040a138: 'ReferencedTimeOffsets',
x0040a13a: 'ReferencedDateTime',
x0040a160: 'TextValue',
x0040a168: 'ConceptCodeSequence',
x0040a170: 'PurposeOfReferenceCodeSequence',
x0040a180: 'AnnotationGroupNumber',
x0040a195: 'ModifierCodeSequence',
x0040a300: 'MeasuredValueSequence',
x0040a301: 'NumericValueQualifierCodeSequence',
x0040a30a: 'NumericValue',
x0040a353: 'AddressTrial',
x0040a354: 'TelephoneNumberTrial',
x0040a360: 'PredecessorDocumentsSequence',
x0040a370: 'ReferencedRequestSequence',
x0040a372: 'PerformedProcedureCodeSequence',
x0040a375: 'CurrentRequestedProcEvidenceSeq',
x0040a385: 'PertinentOtherEvidenceSequence',
x0040a390: 'HL7StructuredDocumentRefSeq',
x0040a491: 'CompletionFlag',
x0040a492: 'CompletionFlagDescription',
x0040a493: 'VerificationFlag',
x0040a494: 'ArchiveRequested',
x0040a496: 'PreliminaryFlag',
x0040a504: 'ContentTemplateSequence',
x0040a525: 'IdenticalDocumentsSequence',
x0040a730: 'ContentSequence',
x0040b020: 'AnnotationSequence',
x0040db00: 'TemplateIdentifier',
x0040db06: 'TemplateVersion',
x0040db07: 'TemplateLocalVersion',
x0040db0b: 'TemplateExtensionFlag',
x0040db0c: 'TemplateExtensionOrganizationUID',
x0040db0d: 'TemplateExtensionCreatorUID',
x0040db73: 'ReferencedContentItemIdentifier',
x0040e001: 'HL7InstanceIdentifier',
x0040e004: 'HL7DocumentEffectiveTime',
x0040e006: 'HL7DocumentTypeCodeSequence',
x0040e010: 'RetrieveURI',
x0040e011: 'RetrieveLocationUID',
x00420010: 'DocumentTitle',
x00420011: 'EncapsulatedDocument',
x00420012: 'MIMETypeOfEncapsulatedDocument',
x00420013: 'SourceInstanceSequence',
x00420014: 'ListOfMIMETypes',
// x00431001: 'BitmapOfPrescanOptions',
// x00431002: 'GradientOffsetInX',
// x00431003: 'GradientOffsetInY',
// x00431004: 'GradientOffsetInZ',
// x00431005: 'ImgIsOriginalOrUnoriginal',
// x00431006: 'NumberOfEPIShots',
// x00431007: 'ViewsPerSegment',
// x00431008: 'RespiratoryRateBpm',
// x00431009: 'RespiratoryTriggerPoint',
// x0043100a: 'TypeOfReceiverUsed',
// x0043100b: 'PeakRateOfChangeOfGradientField',
// x0043100c: 'LimitsInUnitsOfPercent',
// x0043100d: 'PSDEstimatedLimit',
// x0043100e: 'PSDEstimatedLimitInTeslaPerSecond',
// x0043100f: 'Saravghead',
// x00431010: 'WindowValue',
// x00431011: 'TotalInputViews',
// x00431012: 'X-RayChain',
// x00431013: 'DeconKernelParameters',
// x00431014: 'CalibrationParameters',
// x00431015: 'TotalOutputViews',
// x00431016: 'NumberOfOverranges',
// x00431017: 'IBHImageScaleFactors',
// x00431018: 'BBHCoefficients',
// x00431019: 'NumberOfBBHChainsToBlend',
// x0043101a: 'StartingChannelNumber',
// x0043101b: 'PpscanParameters',
// x0043101c: 'GEImageIntegrity',
// x0043101d: 'LevelValue',
// x0043101e: 'DeltaStartTime',
// x0043101f: 'MaxOverrangesInAView',
// x00431020: 'AvgOverrangesAllViews',
// x00431021: 'CorrectedAfterGlowTerms',
// x00431025: 'ReferenceChannels',
// x00431026: 'NoViewsRefChansBlocked',
// x00431027: 'ScanPitchRatio',
// x00431028: 'UniqueImageIden',
// x00431029: 'HistogramTables',
// x0043102a: 'UserDefinedData',
// x0043102b: 'PrivateScanOptions',
// x0043102c: 'EffectiveEchoSpacing',
// x0043102d: 'StringSlopField1',
// x0043102e: 'StringSlopField2',
// x0043102f: 'RawDataType',
// x00431030: 'RawDataType',
// x00431031: 'RACordOfTargetReconCenter',
// x00431032: 'RawDataType',
// x00431033: 'NegScanspacing',
// x00431034: 'OffsetFrequency',
// x00431035: 'UserUsageTag',
// x00431036: 'UserFillMapMSW',
// x00431037: 'UserFillMapLSW',
// x00431038: 'User25-48',
// x00431039: 'SlopInt6-9',
// x00431040: 'TriggerOnPosition',
// x00431041: 'DegreeOfRotation',
// x00431042: 'DASTriggerSource',
// x00431043: 'DASFpaGain',
// x00431044: 'DASOutputSource',
// x00431045: 'DASAdInput',
// x00431046: 'DASCalMode',
// x00431047: 'DASCalFrequency',
// x00431048: 'DASRegXm',
// x00431049: 'DASAutoZero',
// x0043104a: 'StartingChannelOfView',
// x0043104b: 'DASXmPattern',
// x0043104c: 'TGGCTriggerMode',
// x0043104d: 'StartScanToXrayOnDelay',
// x0043104e: 'DurationOfXrayOn',
// x00431060: 'SlopInt10-17',
// x00431061: 'ScannerStudyEntityUID',
// x00431062: 'ScannerStudyID',
// x0043106f: 'ScannerTableEntry',
x00440001: 'ProductPackageIdentifier',
x00440002: 'SubstanceAdministrationApproval',
x00440003: 'ApprovalStatusFurtherDescription',
x00440004: 'ApprovalStatusDateTime',
x00440007: 'ProductTypeCodeSequence',
x00440008: 'ProductName',
x00440009: 'ProductDescription',
x0044000a: 'ProductLotIdentifier',
x0044000b: 'ProductExpirationDateTime',
x00440010: 'SubstanceAdministrationDateTime',
x00440011: 'SubstanceAdministrationNotes',
x00440012: 'SubstanceAdministrationDeviceID',
x00440013: 'ProductParameterSequence',
x00440019: 'SubstanceAdminParameterSeq',
// x00451001: 'NumberOfMacroRowsInDetector',
// x00451002: 'MacroWidthAtISOCenter',
// x00451003: 'DASType',
// x00451004: 'DASGain',
// x00451005: 'DASTemperature',
// x00451006: 'TableDirectionInOrOut',
// x00451007: 'ZSmoothingFactor',
// x00451008: 'ViewWeightingMode',
// x00451009: 'SigmaRowNumberWhichRowsWereUsed',
// x0045100a: 'MinimumDasValueFoundInTheScanData',
// x0045100b: 'MaximumOffsetShiftValueUsed',
// x0045100c: 'NumberOfViewsShifted',
// x0045100d: 'ZTrackingFlag',
// x0045100e: 'MeanZError',
// x0045100f: 'ZTrackingMaximumError',
// x00451010: 'StartingViewForRow2a',
// x00451011: 'NumberOfViewsInRow2a',
// x00451012: 'StartingViewForRow1a',
// x00451013: 'SigmaMode',
// x00451014: 'NumberOfViewsInRow1a',
// x00451015: 'StartingViewForRow2b',
// x00451016: 'NumberOfViewsInRow2b',
// x00451017: 'StartingViewForRow1b',
// x00451018: 'NumberOfViewsInRow1b',
// x00451019: 'AirFilterCalibrationDate',
// x0045101a: 'AirFilterCalibrationTime',
// x0045101b: 'PhantomCalibrationDate',
// x0045101c: 'PhantomCalibrationTime',
// x0045101d: 'ZSlopeCalibrationDate',
// x0045101e: 'ZSlopeCalibrationTime',
// x0045101f: 'CrosstalkCalibrationDate',
// x00451020: 'CrosstalkCalibrationTime',
// x00451021: 'IterboneOptionFlag',
// x00451022: 'PeristalticFlagOption',
x00460012: 'LensDescription',
x00460014: 'RightLensSequence',
x00460015: 'LeftLensSequence',
x00460018: 'CylinderSequence',
x00460028: 'PrismSequence',
x00460030: 'HorizontalPrismPower',
x00460032: 'HorizontalPrismBase',
x00460034: 'VerticalPrismPower',
x00460036: 'VerticalPrismBase',
x00460038: 'LensSegmentType',
x00460040: 'OpticalTransmittance',
x00460042: 'ChannelWidth',
x00460044: 'PupilSize',
x00460046: 'CornealSize',
x00460060: 'DistancePupillaryDistance',
x00460062: 'NearPupillaryDistance',
x00460064: 'OtherPupillaryDistance',
x00460075: 'RadiusOfCurvature',
x00460076: 'KeratometricPower',
x00460077: 'KeratometricAxis',
x00460092: 'BackgroundColor',
x00460094: 'Optotype',
x00460095: 'OptotypePresentation',
x00460100: 'AddNearSequence',
x00460101: 'AddIntermediateSequence',
x00460102: 'AddOtherSequence',
x00460104: 'AddPower',
x00460106: 'ViewingDistance',
x00460125: 'ViewingDistanceType',
x00460135: 'VisualAcuityModifiers',
x00460137: 'DecimalVisualAcuity',
x00460139: 'OptotypeDetailedDefinition',
x00460146: 'SpherePower',
x00460147: 'CylinderPower',
x00500004: 'CalibrationImage',
x00500010: 'DeviceSequence',
x00500014: 'DeviceLength',
x00500015: 'ContainerComponentWidth',
x00500016: 'DeviceDiameter',
x00500017: 'DeviceDiameterUnits',
x00500018: 'DeviceVolume',
x00500019: 'InterMarkerDistance',
x0050001b: 'ContainerComponentID',
x00500020: 'DeviceDescription',
x00540010: 'EnergyWindowVector',
x00540011: 'NumberOfEnergyWindows',
x00540012: 'EnergyWindowInformationSequence',
x00540013: 'EnergyWindowRangeSequence',
x00540014: 'EnergyWindowLowerLimit',
x00540015: 'EnergyWindowUpperLimit',
x00540016: 'RadiopharmaceuticalInformationSeq',
x00540017: 'ResidualSyringeCounts',
x00540018: 'EnergyWindowName',
x00540020: 'DetectorVector',
x00540021: 'NumberOfDetectors',
x00540022: 'DetectorInformationSequence',
x00540030: 'PhaseVector',
x00540031: 'NumberOfPhases',
x00540032: 'PhaseInformationSequence',
x00540033: 'NumberOfFramesInPhase',
x00540036: 'PhaseDelay',
x00540038: 'PauseBetweenFrames',
x00540039: 'PhaseDescription',
x00540050: 'RotationVector',
x00540051: 'NumberOfRotations',
x00540052: 'RotationInformationSequence',
x00540053: 'NumberOfFramesInRotation',
x00540060: 'RRIntervalVector',
x00540061: 'NumberOfRRIntervals',
x00540062: 'GatedInformationSequence',
x00540063: 'DataInformationSequence',
x00540070: 'TimeSlotVector',
x00540071: 'NumberOfTimeSlots',
x00540072: 'TimeSlotInformationSequence',
x00540073: 'TimeSlotTime',
x00540080: 'SliceVector',
x00540081: 'NumberOfSlices',
x00540090: 'AngularViewVector',
x00540100: 'TimeSliceVector',
x00540101: 'NumberOfTimeSlices',
x00540200: 'StartAngle',
x00540202: 'TypeOfDetectorMotion',
x00540210: 'TriggerVector',
x00540211: 'NumberOfTriggersInPhase',
x00540220: 'ViewCodeSequence',
x00540222: 'ViewModifierCodeSequence',
x00540300: 'RadionuclideCodeSequence',
x00540302: 'AdministrationRouteCodeSequence',
x00540304: 'RadiopharmaceuticalCodeSequence',
x00540306: 'CalibrationDataSequence',
x00540308: 'EnergyWindowNumber',
x00540400: 'ImageID',
x00540410: 'PatientOrientationCodeSequence',
x00540412: 'PatientOrientationModifierCodeSeq',
x00540414: 'PatientGantryRelationshipCodeSeq',
x00540500: 'SliceProgressionDirection',
x00541000: 'SeriesType',
x00541001: 'Units',
x00541002: 'CountsSource',
x00541004: 'ReprojectionMethod',
x00541100: 'RandomsCorrectionMethod',
x00541101: 'AttenuationCorrectionMethod',
x00541102: 'DecayCorrection',
x00541103: 'ReconstructionMethod',
x00541104: 'DetectorLinesOfResponseUsed',
x00541105: 'ScatterCorrectionMethod',
x00541200: 'AxialAcceptance',
x00541201: 'AxialMash',
x00541202: 'TransverseMash',
x00541203: 'DetectorElementSize',
x00541210: 'CoincidenceWindowWidth',
x00541220: 'SecondaryCountsType',
x00541300: 'FrameReferenceTime',
x00541310: 'PrimaryCountsAccumulated',
x00541311: 'SecondaryCountsAccumulated',
x00541320: 'SliceSensitivityFactor',
x00541321: 'DecayFactor',
x00541322: 'DoseCalibrationFactor',
x00541323: 'ScatterFractionFactor',
x00541324: 'DeadTimeFactor',
x00541330: 'ImageIndex',
x00541400: 'CountsIncluded',
x00541401: 'DeadTimeCorrectionFlag',
x00603000: 'HistogramSequence',
x00603002: 'HistogramNumberOfBins',
x00603004: 'HistogramFirstBinValue',
x00603006: 'HistogramLastBinValue',
x00603008: 'HistogramBinWidth',
x00603010: 'HistogramExplanation',
x00603020: 'HistogramData',
x00620001: 'SegmentationType',
x00620002: 'SegmentSequence',
x00620003: 'SegmentedPropertyCategoryCodeSeq',
x00620004: 'SegmentNumber',
x00620005: 'SegmentLabel',
x00620006: 'SegmentDescription',
x00620008: 'SegmentAlgorithmType',
x00620009: 'SegmentAlgorithmName',
x0062000a: 'SegmentIdentificationSequence',
x0062000b: 'ReferencedSegmentNumber',
x0062000c: 'RecommendedDisplayGrayscaleValue',
x0062000d: 'RecommendedDisplayCIELabValue',
x0062000e: 'MaximumFractionalValue',
x0062000f: 'SegmentedPropertyTypeCodeSequence',
x00620010: 'SegmentationFractionalType',
x00640002: 'DeformableRegistrationSequence',
x00640003: 'SourceFrameOfReferenceUID',
x00640005: 'DeformableRegistrationGridSequence',
x00640007: 'GridDimensions',
x00640008: 'GridResolution',
x00640009: 'VectorGridData',
x0064000f: 'PreDeformationMatrixRegistSeq',
x00640010: 'PostDeformationMatrixRegistSeq',
x00660001: 'NumberOfSurfaces',
x00660002: 'SurfaceSequence',
x00660003: 'SurfaceNumber',
x00660004: 'SurfaceComments',
x00660009: 'SurfaceProcessing',
x0066000a: 'SurfaceProcessingRatio',
x0066000e: 'FiniteVolume',
x00660010: 'Manifold',
x00660011: 'SurfacePointsSequence',
x00660015: 'NumberOfSurfacePoints',
x00660016: 'PointCoordinatesData',
x00660017: 'PointPositionAccuracy',
x00660018: 'MeanPointDistance',
x00660019: 'MaximumPointDistance',
x0066001b: 'AxisOfRotation',
x0066001c: 'CenterOfRotation',
x0066001e: 'NumberOfVectors',
x0066001f: 'VectorDimensionality',
x00660020: 'VectorAccuracy',
x00660021: 'VectorCoordinateData',
x00660023: 'TrianglePointIndexList',
x00660024: 'EdgePointIndexList',
x00660025: 'VertexPointIndexList',
x00660026: 'TriangleStripSequence',
x00660027: 'TriangleFanSequence',
x00660028: 'LineSequence',
x00660029: 'PrimitivePointIndexList',
x0066002a: 'SurfaceCount',
x0066002f: 'AlgorithmFamilyCodeSequ',
x00660031: 'AlgorithmVersion',
x00660032: 'AlgorithmParameters',
x00660034: 'FacetSequence',
x00660036: 'AlgorithmName',
x00700001: 'GraphicAnnotationSequence',
x00700002: 'GraphicLayer',
x00700003: 'BoundingBoxAnnotationUnits',
x00700004: 'AnchorPointAnnotationUnits',
x00700005: 'GraphicAnnotationUnits',
x00700006: 'UnformattedTextValue',
x00700008: 'TextObjectSequence',
x00700009: 'GraphicObjectSequence',
x00700010: 'BoundingBoxTopLeftHandCorner',
x00700011: 'BoundingBoxBottomRightHandCorner',
x00700012: 'BoundingBoxTextHorizJustification',
x00700014: 'AnchorPoint',
x00700015: 'AnchorPointVisibility',
x00700020: 'GraphicDimensions',
x00700021: 'NumberOfGraphicPoints',
x00700022: 'GraphicData',
x00700023: 'GraphicType',
x00700024: 'GraphicFilled',
x00700040: 'ImageRotationRetired',
x00700041: 'ImageHorizontalFlip',
x00700042: 'ImageRotation',
x00700050: 'DisplayedAreaTopLeftTrial',
x00700051: 'DisplayedAreaBottomRightTrial',
x00700052: 'DisplayedAreaTopLeft',
x00700053: 'DisplayedAreaBottomRight',
x0070005a: 'DisplayedAreaSelectionSequence',
x00700060: 'GraphicLayerSequence',
x00700062: 'GraphicLayerOrder',
x00700066: 'GraphicLayerRecDisplayGraysclValue',
x00700067: 'GraphicLayerRecDisplayRGBValue',
x00700068: 'GraphicLayerDescription',
x00700080: 'ContentLabel',
x00700081: 'ContentDescription',
x00700082: 'PresentationCreationDate',
x00700083: 'PresentationCreationTime',
x00700084: 'ContentCreatorName',
x00700086: 'ContentCreatorIDCodeSequence',
x00700100: 'PresentationSizeMode',
x00700101: 'PresentationPixelSpacing',
x00700102: 'PresentationPixelAspectRatio',
x00700103: 'PresentationPixelMagRatio',
x00700306: 'ShapeType',
x00700308: 'RegistrationSequence',
x00700309: 'MatrixRegistrationSequence',
x0070030a: 'MatrixSequence',
x0070030c: 'FrameOfRefTransformationMatrixType',
x0070030d: 'RegistrationTypeCodeSequence',
x0070030f: 'FiducialDescription',
x00700310: 'FiducialIdentifier',
x00700311: 'FiducialIdentifierCodeSequence',
x00700312: 'ContourUncertaintyRadius',
x00700314: 'UsedFiducialsSequence',
x00700318: 'GraphicCoordinatesDataSequence',
x0070031a: 'FiducialUID',
x0070031c: 'FiducialSetSequence',
x0070031e: 'FiducialSequence',
x00700401: 'GraphicLayerRecomDisplayCIELabVal',
x00700402: 'BlendingSequence',
x00700403: 'RelativeOpacity',
x00700404: 'ReferencedSpatialRegistrationSeq',
x00700405: 'BlendingPosition',
x00720002: 'HangingProtocolName',
x00720004: 'HangingProtocolDescription',
x00720006: 'HangingProtocolLevel',
x00720008: 'HangingProtocolCreator',
x0072000a: 'HangingProtocolCreationDateTime',
x0072000c: 'HangingProtocolDefinitionSequence',
x0072000e: 'HangingProtocolUserIDCodeSequence',
x00720010: 'HangingProtocolUserGroupName',
x00720012: 'SourceHangingProtocolSequence',
x00720014: 'NumberOfPriorsReferenced',
x00720020: 'ImageSetsSequence',
x00720022: 'ImageSetSelectorSequence',
x00720024: 'ImageSetSelectorUsageFlag',
x00720026: 'SelectorAttribute',
x00720028: 'SelectorValueNumber',
x00720030: 'TimeBasedImageSetsSequence',
x00720032: 'ImageSetNumber',
x00720034: 'ImageSetSelectorCategory',
x00720038: 'RelativeTime',
x0072003a: 'RelativeTimeUnits',
x0072003c: 'AbstractPriorValue',
x0072003e: 'AbstractPriorCodeSequence',
x00720040: 'ImageSetLabel',
x00720050: 'SelectorAttributeVR',
x00720052: 'SelectorSequencePointer',
x00720054: 'SelectorSeqPointerPrivateCreator',
x00720056: 'SelectorAttributePrivateCreator',
x00720060: 'SelectorATValue',
x00720062: 'SelectorCSValue',
x00720064: 'SelectorISValue',
x00720066: 'SelectorLOValue',
x00720068: 'SelectorLTValue',
x0072006a: 'SelectorPNValue',
x0072006c: 'SelectorSHValue',
x0072006e: 'SelectorSTValue',
x00720070: 'SelectorUTValue',
x00720072: 'SelectorDSValue',
x00720074: 'SelectorFDValue',
x00720076: 'SelectorFLValue',
x00720078: 'SelectorULValue',
x0072007a: 'SelectorUSValue',
x0072007c: 'SelectorSLValue',
x0072007e: 'SelectorSSValue',
x00720080: 'SelectorCodeSequenceValue',
x00720100: 'NumberOfScreens',
x00720102: 'NominalScreenDefinitionSequence',
x00720104: 'NumberOfVerticalPixels',
x00720106: 'NumberOfHorizontalPixels',
x00720108: 'DisplayEnvironmentSpatialPosition',
x0072010a: 'ScreenMinimumGrayscaleBitDepth',
x0072010c: 'ScreenMinimumColorBitDepth',
x0072010e: 'ApplicationMaximumRepaintTime',
x00720200: 'DisplaySetsSequence',
x00720202: 'DisplaySetNumber',
x00720203: 'DisplaySetLabel',
x00720204: 'DisplaySetPresentationGroup',
x00720206: 'DisplaySetPresentationGroupDescr',
x00720208: 'PartialDataDisplayHandling',
x00720210: 'SynchronizedScrollingSequence',
x00720212: 'DisplaySetScrollingGroup',
x00720214: 'NavigationIndicatorSequence',
x00720216: 'NavigationDisplaySet',
x00720218: 'ReferenceDisplaySets',
x00720300: 'ImageBoxesSequence',
x00720302: 'ImageBoxNumber',
x00720304: 'ImageBoxLayoutType',
x00720306: 'ImageBoxTileHorizontalDimension',
x00720308: 'ImageBoxTileVerticalDimension',
x00720310: 'ImageBoxScrollDirection',
x00720312: 'ImageBoxSmallScrollType',
x00720314: 'ImageBoxSmallScrollAmount',
x00720316: 'ImageBoxLargeScrollType',
x00720318: 'ImageBoxLargeScrollAmount',
x00720320: 'ImageBoxOverlapPriority',
x00720330: 'CineRelativeToRealTime',
x00720400: 'FilterOperationsSequence',
x00720402: 'FilterByCategory',
x00720404: 'FilterByAttributePresence',
x00720406: 'FilterByOperator',
x00720432: 'SynchronizedImageBoxList',
x00720434: 'TypeOfSynchronization',
x00720500: 'BlendingOperationType',
x00720510: 'ReformattingOperationType',
x00720512: 'ReformattingThickness',
x00720514: 'ReformattingInterval',
x00720516: 'ReformattingOpInitialViewDir',
x00720520: 'RenderingType3D',
x00720600: 'SortingOperationsSequence',
x00720602: 'SortByCategory',
x00720604: 'SortingDirection',
x00720700: 'DisplaySetPatientOrientation',
x00720702: 'VOIType',
x00720704: 'PseudoColorType',
x00720706: 'ShowGrayscaleInverted',
x00720710: 'ShowImageTrueSizeFlag',
x00720712: 'ShowGraphicAnnotationFlag',
x00720714: 'ShowPatientDemographicsFlag',
x00720716: 'ShowAcquisitionTechniquesFlag',
x00720717: 'DisplaySetHorizontalJustification',
x00720718: 'DisplaySetVerticalJustification',
x00741000: 'UnifiedProcedureStepState',
x00741002: 'UPSProgressInformationSequence',
x00741004: 'UnifiedProcedureStepProgress',
x00741006: 'UnifiedProcedureStepProgressDescr',
x00741008: 'UnifiedProcedureStepComURISeq',
x0074100a: 'ContactURI',
x0074100c: 'ContactDisplayName',
x00741020: 'BeamTaskSequence',
x00741022: 'BeamTaskType',
x00741024: 'BeamOrderIndex',
x00741030: 'DeliveryVerificationImageSequence',
x00741032: 'VerificationImageTiming',
x00741034: 'DoubleExposureFlag',
x00741036: 'DoubleExposureOrdering',
x00741038: 'DoubleExposureMeterset',
x0074103a: 'DoubleExposureFieldDelta',
x00741040: 'RelatedReferenceRTImageSequence',
x00741042: 'GeneralMachineVerificationSequence',
x00741044: 'ConventionalMachineVerificationSeq',
x00741046: 'IonMachineVerificationSequence',
x00741048: 'FailedAttributesSequence',
x0074104a: 'OverriddenAttributesSequence',
x0074104c: 'ConventionalControlPointVerifySeq',
x0074104e: 'IonControlPointVerificationSeq',
x00741050: 'AttributeOccurrenceSequence',
x00741052: 'AttributeOccurrencePointer',
x00741054: 'AttributeItemSelector',
x00741056: 'AttributeOccurrencePrivateCreator',
x00741200: 'ScheduledProcedureStepPriority',
x00741202: 'StudyListLabel',
x00741204: 'ProcedureStepLabel',
x00741210: 'ScheduledProcessingParametersSeq',
x00741212: 'PerformedProcessingParametersSeq',
x00741216: 'UPSPerformedProcedureSequence',
x00741220: 'RelatedProcedureStepSequence',
x00741222: 'ProcedureStepRelationshipType',
x00741230: 'DeletionLock',
x00741234: 'ReceivingAE',
x00741236: 'RequestingAE',
x00741238: 'ReasonForCancellation',
x00741242: 'SCPStatus',
x00741244: 'SubscriptionListStatus',
x00741246: 'UPSListStatus',
x00880130: 'StorageMediaFileSetID',
x00880140: 'StorageMediaFileSetUID',
x00880200: 'IconImageSequence',
x00880904: 'TopicTitle',
x00880906: 'TopicSubject',
x00880910: 'TopicAuthor',
x00880912: 'TopicKeywords',
x01000410: 'SOPInstanceStatus',
x01000420: 'SOPAuthorizationDateAndTime',
x01000424: 'SOPAuthorizationComment',
x01000426: 'AuthorizationEquipmentCertNumber',
x04000005: 'MACIDNumber',
x04000010: 'MACCalculationTransferSyntaxUID',
x04000015: 'MACAlgorithm',
x04000020: 'DataElementsSigned',
x04000100: 'DigitalSignatureUID',
x04000105: 'DigitalSignatureDateTime',
x04000110: 'CertificateType',
x04000115: 'CertificateOfSigner',
x04000120: 'Signature',
x04000305: 'CertifiedTimestampType',
x04000310: 'CertifiedTimestamp',
x04000401: 'DigitalSignaturePurposeCodeSeq',
x04000402: 'ReferencedDigitalSignatureSeq',
x04000403: 'ReferencedSOPInstanceMACSeq',
x04000404: 'MAC',
x04000500: 'EncryptedAttributesSequence',
x04000510: 'EncryptedContentTransferSyntaxUID',
x04000520: 'EncryptedContent',
x04000550: 'ModifiedAttributesSequence',
x04000561: 'OriginalAttributesSequence',
x04000562: 'AttributeModificationDateTime',
x04000563: 'ModifyingSystem',
x04000564: 'SourceOfPreviousValues',
x04000565: 'ReasonForTheAttributeModification',
x1000xxx0: 'EscapeTriplet',
x1000xxx1: 'RunLengthTriplet',
x1000xxx2: 'HuffmanTableSize',
x1000xxx3: 'HuffmanTableTriplet',
x1000xxx4: 'ShiftTableSize',
x1000xxx5: 'ShiftTableTriplet',
x1010xxxx: 'ZonalMap',
x20000010: 'NumberOfCopies',
x2000001e: 'PrinterConfigurationSequence',
x20000020: 'PrintPriority',
x20000030: 'MediumType',
x20000040: 'FilmDestination',
x20000050: 'FilmSessionLabel',
x20000060: 'MemoryAllocation',
x20000061: 'MaximumMemoryAllocation',
x20000062: 'ColorImagePrintingFlag',
x20000063: 'CollationFlag',
x20000065: 'AnnotationFlag',
x20000067: 'ImageOverlayFlag',
x20000069: 'PresentationLUTFlag',
x2000006a: 'ImageBoxPresentationLUTFlag',
x200000a0: 'MemoryBitDepth',
x200000a1: 'PrintingBitDepth',
x200000a2: 'MediaInstalledSequence',
x200000a4: 'OtherMediaAvailableSequence',
x200000a8: 'SupportedImageDisplayFormatSeq',
x20000500: 'ReferencedFilmBoxSequence',
x20000510: 'ReferencedStoredPrintSequence',
x20100010: 'ImageDisplayFormat',
x20100030: 'AnnotationDisplayFormatID',
x20100040: 'FilmOrientation',
x20100050: 'FilmSizeID',
x20100052: 'PrinterResolutionID',
x20100054: 'DefaultPrinterResolutionID',
x20100060: 'MagnificationType',
x20100080: 'SmoothingType',
x201000a6: 'DefaultMagnificationType',
x201000a7: 'OtherMagnificationTypesAvailable',
x201000a8: 'DefaultSmoothingType',
x201000a9: 'OtherSmoothingTypesAvailable',
x20100100: 'BorderDensity',
x20100110: 'EmptyImageDensity',
x20100120: 'MinDensity',
x20100130: 'MaxDensity',
x20100140: 'Trim',
x20100150: 'ConfigurationInformation',
x20100152: 'ConfigurationInformationDescr',
x20100154: 'MaximumCollatedFilms',
x2010015e: 'Illumination',
x20100160: 'ReflectedAmbientLight',
x20100376: 'PrinterPixelSpacing',
x20100500: 'ReferencedFilmSessionSequence',
x20100510: 'ReferencedImageBoxSequence',
x20100520: 'ReferencedBasicAnnotationBoxSeq',
x20200010: 'ImageBoxPosition',
x20200020: 'Polarity',
x20200030: 'RequestedImageSize',
x20200040: 'RequestedDecimate-CropBehavior',
x20200050: 'RequestedResolutionID',
x202000a0: 'RequestedImageSizeFlag',
x202000a2: 'DecimateCropResult',
x20200110: 'BasicGrayscaleImageSequence',
x20200111: 'BasicColorImageSequence',
x20200130: 'ReferencedImageOverlayBoxSequence',
x20200140: 'ReferencedVOILUTBoxSequence',
x20300010: 'AnnotationPosition',
x20300020: 'TextString',
x20400010: 'ReferencedOverlayPlaneSequence',
x20400011: 'ReferencedOverlayPlaneGroups',
x20400020: 'OverlayPixelDataSequence',
x20400060: 'OverlayMagnificationType',
x20400070: 'OverlaySmoothingType',
x20400072: 'OverlayOrImageMagnification',
x20400074: 'MagnifyToNumberOfColumns',
x20400080: 'OverlayForegroundDensity',
x20400082: 'OverlayBackgroundDensity',
x20400090: 'OverlayMode',
x20400100: 'ThresholdDensity',
x20400500: 'ReferencedImageBoxSequenceRetired',
x20500010: 'PresentationLUTSequence',
x20500020: 'PresentationLUTShape',
x20500500: 'ReferencedPresentationLUTSequence',
x21000010: 'PrintJobID',
x21000020: 'ExecutionStatus',
x21000030: 'ExecutionStatusInfo',
x21000040: 'CreationDate',
x21000050: 'CreationTime',
x21000070: 'Originator',
x21000140: 'DestinationAE',
x21000160: 'OwnerID',
x21000170: 'NumberOfFilms',
x21000500: 'ReferencedPrintJobSequencePullStoredPrint',
x21100010: 'PrinterStatus',
x21100020: 'PrinterStatusInfo',
x21100030: 'PrinterName',
x21100099: 'PrintQueueID',
x21200010: 'QueueStatus',
x21200050: 'PrintJobDescriptionSequence',
x21200070: 'ReferencedPrintJobSequence',
x21300010: 'PrintManagementCapabilitiesSeq',
x21300015: 'PrinterCharacteristicsSequence',
x21300030: 'FilmBoxContentSequence',
x21300040: 'ImageBoxContentSequence',
x21300050: 'AnnotationContentSequence',
x21300060: 'ImageOverlayBoxContentSequence',
x21300080: 'PresentationLUTContentSequence',
x213000a0: 'ProposedStudySequence',
x213000c0: 'OriginalImageSequence',
x22000001: 'LabelFromInfoExtractedFromInstance',
x22000002: 'LabelText',
x22000003: 'LabelStyleSelection',
x22000004: 'MediaDisposition',
x22000005: 'BarcodeValue',
x22000006: 'BarcodeSymbology',
x22000007: 'AllowMediaSplitting',
x22000008: 'IncludeNonDICOMObjects',
x22000009: 'IncludeDisplayApplication',
x2200000a: 'SaveCompInstancesAfterMediaCreate',
x2200000b: 'TotalNumberMediaPiecesCreated',
x2200000c: 'RequestedMediaApplicationProfile',
x2200000d: 'ReferencedStorageMediaSequence',
x2200000e: 'FailureAttributes',
x2200000f: 'AllowLossyCompression',
x22000020: 'RequestPriority',
x30020002: 'RTImageLabel',
x30020003: 'RTImageName',
x30020004: 'RTImageDescription',
x3002000a: 'ReportedValuesOrigin',
x3002000c: 'RTImagePlane',
x3002000d: 'XRayImageReceptorTranslation',
x3002000e: 'XRayImageReceptorAngle',
x30020010: 'RTImageOrientation',
x30020011: 'ImagePlanePixelSpacing',
x30020012: 'RTImagePosition',
x30020020: 'RadiationMachineName',
x30020022: 'RadiationMachineSAD',
x30020024: 'RadiationMachineSSD',
x30020026: 'RTImageSID',
x30020028: 'SourceToReferenceObjectDistance',
x30020029: 'FractionNumber',
x30020030: 'ExposureSequence',
x30020032: 'MetersetExposure',
x30020034: 'DiaphragmPosition',
x30020040: 'FluenceMapSequence',
x30020041: 'FluenceDataSource',
x30020042: 'FluenceDataScale',
x30020051: 'FluenceMode',
x30020052: 'FluenceModeID',
x30040001: 'DVHType',
x30040002: 'DoseUnits',
x30040004: 'DoseType',
x30040006: 'DoseComment',
x30040008: 'NormalizationPoint',
x3004000a: 'DoseSummationType',
x3004000c: 'GridFrameOffsetVector',
x3004000e: 'DoseGridScaling',
x30040010: 'RTDoseROISequence',
x30040012: 'DoseValue',
x30040014: 'TissueHeterogeneityCorrection',
x30040040: 'DVHNormalizationPoint',
x30040042: 'DVHNormalizationDoseValue',
x30040050: 'DVHSequence',
x30040052: 'DVHDoseScaling',
x30040054: 'DVHVolumeUnits',
x30040056: 'DVHNumberOfBins',
x30040058: 'DVHData',
x30040060: 'DVHReferencedROISequence',
x30040062: 'DVHROIContributionType',
x30040070: 'DVHMinimumDose',
x30040072: 'DVHMaximumDose',
x30040074: 'DVHMeanDose',
x30060002: 'StructureSetLabel',
x30060004: 'StructureSetName',
x30060006: 'StructureSetDescription',
x30060008: 'StructureSetDate',
x30060009: 'StructureSetTime',
x30060010: 'ReferencedFrameOfReferenceSequence',
x30060012: 'RTReferencedStudySequence',
x30060014: 'RTReferencedSeriesSequence',
x30060016: 'ContourImageSequence',
x30060020: 'StructureSetROISequence',
x30060022: 'ROINumber',
x30060024: 'ReferencedFrameOfReferenceUID',
x30060026: 'ROIName',
x30060028: 'ROIDescription',
x3006002a: 'ROIDisplayColor',
x3006002c: 'ROIVolume',
x30060030: 'RTRelatedROISequence',
x30060033: 'RTROIRelationship',
x30060036: 'ROIGenerationAlgorithm',
x30060038: 'ROIGenerationDescription',
x30060039: 'ROIContourSequence',
x30060040: 'ContourSequence',
x30060042: 'ContourGeometricType',
x30060044: 'ContourSlabThickness',
x30060045: 'ContourOffsetVector',
x30060046: 'NumberOfContourPoints',
x30060048: 'ContourNumber',
x30060049: 'AttachedContours',
x30060050: 'ContourData',
x30060080: 'RTROIObservationsSequence',
x30060082: 'ObservationNumber',
x30060084: 'ReferencedROINumber',
x30060085: 'ROIObservationLabel',
x30060086: 'RTROIIdentificationCodeSequence',
x30060088: 'ROIObservationDescription',
x300600a0: 'RelatedRTROIObservationsSequence',
x300600a4: 'RTROIInterpretedType',
x300600a6: 'ROIInterpreter',
x300600b0: 'ROIPhysicalPropertiesSequence',
x300600b2: 'ROIPhysicalProperty',
x300600b4: 'ROIPhysicalPropertyValue',
x300600b6: 'ROIElementalCompositionSequence',
x300600b7: 'ROIElementalCompAtomicNumber',
x300600b8: 'ROIElementalCompAtomicMassFraction',
x300600c0: 'FrameOfReferenceRelationshipSeq',
x300600c2: 'RelatedFrameOfReferenceUID',
x300600c4: 'FrameOfReferenceTransformType',
x300600c6: 'FrameOfReferenceTransformMatrix',
x300600c8: 'FrameOfReferenceTransformComment',
x30080010: 'MeasuredDoseReferenceSequence',
x30080012: 'MeasuredDoseDescription',
x30080014: 'MeasuredDoseType',
x30080016: 'MeasuredDoseValue',
x30080020: 'TreatmentSessionBeamSequence',
x30080021: 'TreatmentSessionIonBeamSequence',
x30080022: 'CurrentFractionNumber',
x30080024: 'TreatmentControlPointDate',
x30080025: 'TreatmentControlPointTime',
x3008002a: 'TreatmentTerminationStatus',
x3008002b: 'TreatmentTerminationCode',
x3008002c: 'TreatmentVerificationStatus',
x30080030: 'ReferencedTreatmentRecordSequence',
x30080032: 'SpecifiedPrimaryMeterset',
x30080033: 'SpecifiedSecondaryMeterset',
x30080036: 'DeliveredPrimaryMeterset',
x30080037: 'DeliveredSecondaryMeterset',
x3008003a: 'SpecifiedTreatmentTime',
x3008003b: 'DeliveredTreatmentTime',
x30080040: 'ControlPointDeliverySequence',
x30080041: 'IonControlPointDeliverySequence',
x30080042: 'SpecifiedMeterset',
x30080044: 'DeliveredMeterset',
x30080045: 'MetersetRateSet',
x30080046: 'MetersetRateDelivered',
x30080047: 'ScanSpotMetersetsDelivered',
x30080048: 'DoseRateDelivered',
x30080050: 'TreatmentSummaryCalcDoseRefSeq',
x30080052: 'CumulativeDoseToDoseReference',
x30080054: 'FirstTreatmentDate',
x30080056: 'MostRecentTreatmentDate',
x3008005a: 'NumberOfFractionsDelivered',
x30080060: 'OverrideSequence',
x30080061: 'ParameterSequencePointer',
x30080062: 'OverrideParameterPointer',
x30080063: 'ParameterItemIndex',
x30080064: 'MeasuredDoseReferenceNumber',
x30080065: 'ParameterPointer',
x30080066: 'OverrideReason',
x30080068: 'CorrectedParameterSequence',
x3008006a: 'CorrectionValue',
x30080070: 'CalculatedDoseReferenceSequence',
x30080072: 'CalculatedDoseReferenceNumber',
x30080074: 'CalculatedDoseReferenceDescription',
x30080076: 'CalculatedDoseReferenceDoseValue',
x30080078: 'StartMeterset',
x3008007a: 'EndMeterset',
x30080080: 'ReferencedMeasuredDoseReferenceSeq',
x30080082: 'ReferencedMeasuredDoseReferenceNum',
x30080090: 'ReferencedCalculatedDoseRefSeq',
x30080092: 'ReferencedCalculatedDoseRefNumber',
x300800a0: 'BeamLimitingDeviceLeafPairsSeq',
x300800b0: 'RecordedWedgeSequence',
x300800c0: 'RecordedCompensatorSequence',
x300800d0: 'RecordedBlockSequence',
x300800e0: 'TreatmentSummaryMeasuredDoseRefSeq',
x300800f0: 'RecordedSnoutSequence',
x300800f2: 'RecordedRangeShifterSequence',
x300800f4: 'RecordedLateralSpreadingDeviceSeq',
x300800f6: 'RecordedRangeModulatorSequence',
x30080100: 'RecordedSourceSequence',
x30080105: 'SourceSerialNumber',
x30080110: 'TreatmentSessionAppSetupSeq',
x30080116: 'ApplicationSetupCheck',
x30080120: 'RecordedBrachyAccessoryDeviceSeq',
x30080122: 'ReferencedBrachyAccessoryDeviceNum',
x30080130: 'RecordedChannelSequence',
x30080132: 'SpecifiedChannelTotalTime',
x30080134: 'DeliveredChannelTotalTime',
x30080136: 'SpecifiedNumberOfPulses',
x30080138: 'DeliveredNumberOfPulses',
x3008013a: 'SpecifiedPulseRepetitionInterval',
x3008013c: 'DeliveredPulseRepetitionInterval',
x30080140: 'RecordedSourceApplicatorSequence',
x30080142: 'ReferencedSourceApplicatorNumber',
x30080150: 'RecordedChannelShieldSequence',
x30080152: 'ReferencedChannelShieldNumber',
x30080160: 'BrachyControlPointDeliveredSeq',
x30080162: 'SafePositionExitDate',
x30080164: 'SafePositionExitTime',
x30080166: 'SafePositionReturnDate',
x30080168: 'SafePositionReturnTime',
x30080200: 'CurrentTreatmentStatus',
x30080202: 'TreatmentStatusComment',
x30080220: 'FractionGroupSummarySequence',
x30080223: 'ReferencedFractionNumber',
x30080224: 'FractionGroupType',
x30080230: 'BeamStopperPosition',
x30080240: 'FractionStatusSummarySequence',
x30080250: 'TreatmentDate',
x30080251: 'TreatmentTime',
x300a0002: 'RTPlanLabel',
x300a0003: 'RTPlanName',
x300a0004: 'RTPlanDescription',
x300a0006: 'RTPlanDate',
x300a0007: 'RTPlanTime',
x300a0009: 'TreatmentProtocols',
x300a000a: 'PlanIntent',
x300a000b: 'TreatmentSites',
x300a000c: 'RTPlanGeometry',
x300a000e: 'PrescriptionDescription',
x300a0010: 'DoseReferenceSequence',
x300a0012: 'DoseReferenceNumber',
x300a0013: 'DoseReferenceUID',
x300a0014: 'DoseReferenceStructureType',
x300a0015: 'NominalBeamEnergyUnit',
x300a0016: 'DoseReferenceDescription',
x300a0018: 'DoseReferencePointCoordinates',
x300a001a: 'NominalPriorDose',
x300a0020: 'DoseReferenceType',
x300a0021: 'ConstraintWeight',
x300a0022: 'DeliveryWarningDose',
x300a0023: 'DeliveryMaximumDose',
x300a0025: 'TargetMinimumDose',
x300a0026: 'TargetPrescriptionDose',
x300a0027: 'TargetMaximumDose',
x300a0028: 'TargetUnderdoseVolumeFraction',
x300a002a: 'OrganAtRiskFullVolumeDose',
x300a002b: 'OrganAtRiskLimitDose',
x300a002c: 'OrganAtRiskMaximumDose',
x300a002d: 'OrganAtRiskOverdoseVolumeFraction',
x300a0040: 'ToleranceTableSequence',
x300a0042: 'ToleranceTableNumber',
x300a0043: 'ToleranceTableLabel',
x300a0044: 'GantryAngleTolerance',
x300a0046: 'BeamLimitingDeviceAngleTolerance',
x300a0048: 'BeamLimitingDeviceToleranceSeq',
x300a004a: 'BeamLimitingDevicePositionTol',
x300a004b: 'SnoutPositionTolerance',
x300a004c: 'PatientSupportAngleTolerance',
x300a004e: 'TableTopEccentricAngleTolerance',
x300a004f: 'TableTopPitchAngleTolerance',
x300a0050: 'TableTopRollAngleTolerance',
x300a0051: 'TableTopVerticalPositionTolerance',
x300a0052: 'TableTopLongitudinalPositionTol',
x300a0053: 'TableTopLateralPositionTolerance',
x300a0055: 'RTPlanRelationship',
x300a0070: 'FractionGroupSequence',
x300a0071: 'FractionGroupNumber',
x300a0072: 'FractionGroupDescription',
x300a0078: 'NumberOfFractionsPlanned',
x300a0079: 'NumberFractionPatternDigitsPerDay',
x300a007a: 'RepeatFractionCycleLength',
x300a007b: 'FractionPattern',
x300a0080: 'NumberOfBeams',
x300a0082: 'BeamDoseSpecificationPoint',
x300a0084: 'BeamDose',
x300a0086: 'BeamMeterset',
x300a0088: 'BeamDosePointDepth',
x300a0089: 'BeamDosePointEquivalentDepth',
x300a008a: 'BeamDosePointSSD',
x300a00a0: 'NumberOfBrachyApplicationSetups',
x300a00a2: 'BrachyAppSetupDoseSpecPoint',
x300a00a4: 'BrachyApplicationSetupDose',
x300a00b0: 'BeamSequence',
x300a00b2: 'TreatmentMachineName',
x300a00b3: 'PrimaryDosimeterUnit',
x300a00b4: 'SourceAxisDistance',
x300a00b6: 'BeamLimitingDeviceSequence',
x300a00b8: 'RTBeamLimitingDeviceType',
x300a00ba: 'SourceToBeamLimitingDeviceDistance',
x300a00bb: 'IsocenterToBeamLimitingDeviceDist',
x300a00bc: 'NumberOfLeafJawPairs',
x300a00be: 'LeafPositionBoundaries',
x300a00c0: 'BeamNumber',
x300a00c2: 'BeamName',
x300a00c3: 'BeamDescription',
x300a00c4: 'BeamType',
x300a00c6: 'RadiationType',
x300a00c7: 'HighDoseTechniqueType',
x300a00c8: 'ReferenceImageNumber',
x300a00ca: 'PlannedVerificationImageSequence',
x300a00cc: 'ImagingDeviceSpecificAcqParams',
x300a00ce: 'TreatmentDeliveryType',
x300a00d0: 'NumberOfWedges',
x300a00d1: 'WedgeSequence',
x300a00d2: 'WedgeNumber',
x300a00d3: 'WedgeType',
x300a00d4: 'WedgeID',
x300a00d5: 'WedgeAngle',
x300a00d6: 'WedgeFactor',
x300a00d7: 'TotalWedgeTrayWaterEquivThickness',
x300a00d8: 'WedgeOrientation',
x300a00d9: 'IsocenterToWedgeTrayDistance',
x300a00da: 'SourceToWedgeTrayDistance',
x300a00db: 'WedgeThinEdgePosition',
x300a00dc: 'BolusID',
x300a00dd: 'BolusDescription',
x300a00e0: 'NumberOfCompensators',
x300a00e1: 'MaterialID',
x300a00e2: 'TotalCompensatorTrayFactor',
x300a00e3: 'CompensatorSequence',
x300a00e4: 'CompensatorNumber',
x300a00e5: 'CompensatorID',
x300a00e6: 'SourceToCompensatorTrayDistance',
x300a00e7: 'CompensatorRows',
x300a00e8: 'CompensatorColumns',
x300a00e9: 'CompensatorPixelSpacing',
x300a00ea: 'CompensatorPosition',
x300a00eb: 'CompensatorTransmissionData',
x300a00ec: 'CompensatorThicknessData',
x300a00ed: 'NumberOfBoli',
x300a00ee: 'CompensatorType',
x300a00f0: 'NumberOfBlocks',
x300a00f2: 'TotalBlockTrayFactor',
x300a00f3: 'TotalBlockTrayWaterEquivThickness',
x300a00f4: 'BlockSequence',
x300a00f5: 'BlockTrayID',
x300a00f6: 'SourceToBlockTrayDistance',
x300a00f7: 'IsocenterToBlockTrayDistance',
x300a00f8: 'BlockType',
x300a00f9: 'AccessoryCode',
x300a00fa: 'BlockDivergence',
x300a00fb: 'BlockMountingPosition',
x300a00fc: 'BlockNumber',
x300a00fe: 'BlockName',
x300a0100: 'BlockThickness',
x300a0102: 'BlockTransmission',
x300a0104: 'BlockNumberOfPoints',
x300a0106: 'BlockData',
x300a0107: 'ApplicatorSequence',
x300a0108: 'ApplicatorID',
x300a0109: 'ApplicatorType',
x300a010a: 'ApplicatorDescription',
x300a010c: 'CumulativeDoseReferenceCoefficient',
x300a010e: 'FinalCumulativeMetersetWeight',
x300a0110: 'NumberOfControlPoints',
x300a0111: 'ControlPointSequence',
x300a0112: 'ControlPointIndex',
x300a0114: 'NominalBeamEnergy',
x300a0115: 'DoseRateSet',
x300a0116: 'WedgePositionSequence',
x300a0118: 'WedgePosition',
x300a011a: 'BeamLimitingDevicePositionSequence',
x300a011c: 'LeafJawPositions',
x300a011e: 'GantryAngle',
x300a011f: 'GantryRotationDirection',
x300a0120: 'BeamLimitingDeviceAngle',
x300a0121: 'BeamLimitingDeviceRotateDirection',
x300a0122: 'PatientSupportAngle',
x300a0123: 'PatientSupportRotationDirection',
x300a0124: 'TableTopEccentricAxisDistance',
x300a0125: 'TableTopEccentricAngle',
x300a0126: 'TableTopEccentricRotateDirection',
x300a0128: 'TableTopVerticalPosition',
x300a0129: 'TableTopLongitudinalPosition',
x300a012a: 'TableTopLateralPosition',
x300a012c: 'IsocenterPosition',
x300a012e: 'SurfaceEntryPoint',
x300a0130: 'SourceToSurfaceDistance',
x300a0134: 'CumulativeMetersetWeight',
x300a0140: 'TableTopPitchAngle',
x300a0142: 'TableTopPitchRotationDirection',
x300a0144: 'TableTopRollAngle',
x300a0146: 'TableTopRollRotationDirection',
x300a0148: 'HeadFixationAngle',
x300a014a: 'GantryPitchAngle',
x300a014c: 'GantryPitchRotationDirection',
x300a014e: 'GantryPitchAngleTolerance',
x300a0180: 'PatientSetupSequence',
x300a0182: 'PatientSetupNumber',
x300a0183: 'PatientSetupLabel',
x300a0184: 'PatientAdditionalPosition',
x300a0190: 'FixationDeviceSequence',
x300a0192: 'FixationDeviceType',
x300a0194: 'FixationDeviceLabel',
x300a0196: 'FixationDeviceDescription',
x300a0198: 'FixationDevicePosition',
x300a0199: 'FixationDevicePitchAngle',
x300a019a: 'FixationDeviceRollAngle',
x300a01a0: 'ShieldingDeviceSequence',
x300a01a2: 'ShieldingDeviceType',
x300a01a4: 'ShieldingDeviceLabel',
x300a01a6: 'ShieldingDeviceDescription',
x300a01a8: 'ShieldingDevicePosition',
x300a01b0: 'SetupTechnique',
x300a01b2: 'SetupTechniqueDescription',
x300a01b4: 'SetupDeviceSequence',
x300a01b6: 'SetupDeviceType',
x300a01b8: 'SetupDeviceLabel',
x300a01ba: 'SetupDeviceDescription',
x300a01bc: 'SetupDeviceParameter',
x300a01d0: 'SetupReferenceDescription',
x300a01d2: 'TableTopVerticalSetupDisplacement',
x300a01d4: 'TableTopLongitudinalSetupDisplace',
x300a01d6: 'TableTopLateralSetupDisplacement',
x300a0200: 'BrachyTreatmentTechnique',
x300a0202: 'BrachyTreatmentType',
x300a0206: 'TreatmentMachineSequence',
x300a0210: 'SourceSequence',
x300a0212: 'SourceNumber',
x300a0214: 'SourceType',
x300a0216: 'SourceManufacturer',
x300a0218: 'ActiveSourceDiameter',
x300a021a: 'ActiveSourceLength',
x300a0222: 'SourceEncapsulationNomThickness',
x300a0224: 'SourceEncapsulationNomTransmission',
x300a0226: 'SourceIsotopeName',
x300a0228: 'SourceIsotopeHalfLife',
x300a0229: 'SourceStrengthUnits',
x300a022a: 'ReferenceAirKermaRate',
x300a022b: 'SourceStrength',
x300a022c: 'SourceStrengthReferenceDate',
x300a022e: 'SourceStrengthReferenceTime',
x300a0230: 'ApplicationSetupSequence',
x300a0232: 'ApplicationSetupType',
x300a0234: 'ApplicationSetupNumber',
x300a0236: 'ApplicationSetupName',
x300a0238: 'ApplicationSetupManufacturer',
x300a0240: 'TemplateNumber',
x300a0242: 'TemplateType',
x300a0244: 'TemplateName',
x300a0250: 'TotalReferenceAirKerma',
x300a0260: 'BrachyAccessoryDeviceSequence',
x300a0262: 'BrachyAccessoryDeviceNumber',
x300a0263: 'BrachyAccessoryDeviceID',
x300a0264: 'BrachyAccessoryDeviceType',
x300a0266: 'BrachyAccessoryDeviceName',
x300a026a: 'BrachyAccessoryDeviceNomThickness',
x300a026c: 'BrachyAccessoryDevNomTransmission',
x300a0280: 'ChannelSequence',
x300a0282: 'ChannelNumber',
x300a0284: 'ChannelLength',
x300a0286: 'ChannelTotalTime',
x300a0288: 'SourceMovementType',
x300a028a: 'NumberOfPulses',
x300a028c: 'PulseRepetitionInterval',
x300a0290: 'SourceApplicatorNumber',
x300a0291: 'SourceApplicatorID',
x300a0292: 'SourceApplicatorType',
x300a0294: 'SourceApplicatorName',
x300a0296: 'SourceApplicatorLength',
x300a0298: 'SourceApplicatorManufacturer',
x300a029c: 'SourceApplicatorWallNomThickness',
x300a029e: 'SourceApplicatorWallNomTrans',
x300a02a0: 'SourceApplicatorStepSize',
x300a02a2: 'TransferTubeNumber',
x300a02a4: 'TransferTubeLength',
x300a02b0: 'ChannelShieldSequence',
x300a02b2: 'ChannelShieldNumber',
x300a02b3: 'ChannelShieldID',
x300a02b4: 'ChannelShieldName',
x300a02b8: 'ChannelShieldNominalThickness',
x300a02ba: 'ChannelShieldNominalTransmission',
x300a02c8: 'FinalCumulativeTimeWeight',
x300a02d0: 'BrachyControlPointSequence',
x300a02d2: 'ControlPointRelativePosition',
x300a02d4: 'ControlPoint3DPosition',
x300a02d6: 'CumulativeTimeWeight',
x300a02e0: 'CompensatorDivergence',
x300a02e1: 'CompensatorMountingPosition',
x300a02e2: 'SourceToCompensatorDistance',
x300a02e3: 'TotalCompTrayWaterEquivThickness',
x300a02e4: 'IsocenterToCompensatorTrayDistance',
x300a02e5: 'CompensatorColumnOffset',
x300a02e6: 'IsocenterToCompensatorDistances',
x300a02e7: 'CompensatorRelStoppingPowerRatio',
x300a02e8: 'CompensatorMillingToolDiameter',
x300a02ea: 'IonRangeCompensatorSequence',
x300a02eb: 'CompensatorDescription',
x300a0302: 'RadiationMassNumber',
x300a0304: 'RadiationAtomicNumber',
x300a0306: 'RadiationChargeState',
x300a0308: 'ScanMode',
x300a030a: 'VirtualSourceAxisDistances',
x300a030c: 'SnoutSequence',
x300a030d: 'SnoutPosition',
x300a030f: 'SnoutID',
x300a0312: 'NumberOfRangeShifters',
x300a0314: 'RangeShifterSequence',
x300a0316: 'RangeShifterNumber',
x300a0318: 'RangeShifterID',
x300a0320: 'RangeShifterType',
x300a0322: 'RangeShifterDescription',
x300a0330: 'NumberOfLateralSpreadingDevices',
x300a0332: 'LateralSpreadingDeviceSequence',
x300a0334: 'LateralSpreadingDeviceNumber',
x300a0336: 'LateralSpreadingDeviceID',
x300a0338: 'LateralSpreadingDeviceType',
x300a033a: 'LateralSpreadingDeviceDescription',
x300a033c: 'LateralSpreadingDevWaterEquivThick',
x300a0340: 'NumberOfRangeModulators',
x300a0342: 'RangeModulatorSequence',
x300a0344: 'RangeModulatorNumber',
x300a0346: 'RangeModulatorID',
x300a0348: 'RangeModulatorType',
x300a034a: 'RangeModulatorDescription',
x300a034c: 'BeamCurrentModulationID',
x300a0350: 'PatientSupportType',
x300a0352: 'PatientSupportID',
x300a0354: 'PatientSupportAccessoryCode',
x300a0356: 'FixationLightAzimuthalAngle',
x300a0358: 'FixationLightPolarAngle',
x300a035a: 'MetersetRate',
x300a0360: 'RangeShifterSettingsSequence',
x300a0362: 'RangeShifterSetting',
x300a0364: 'IsocenterToRangeShifterDistance',
x300a0366: 'RangeShifterWaterEquivThickness',
x300a0370: 'LateralSpreadingDeviceSettingsSeq',
x300a0372: 'LateralSpreadingDeviceSetting',
x300a0374: 'IsocenterToLateralSpreadingDevDist',
x300a0380: 'RangeModulatorSettingsSequence',
x300a0382: 'RangeModulatorGatingStartValue',
x300a0384: 'RangeModulatorGatingStopValue',
x300a038a: 'IsocenterToRangeModulatorDistance',
x300a0390: 'ScanSpotTuneID',
x300a0392: 'NumberOfScanSpotPositions',
x300a0394: 'ScanSpotPositionMap',
x300a0396: 'ScanSpotMetersetWeights',
x300a0398: 'ScanningSpotSize',
x300a039a: 'NumberOfPaintings',
x300a03a0: 'IonToleranceTableSequence',
x300a03a2: 'IonBeamSequence',
x300a03a4: 'IonBeamLimitingDeviceSequence',
x300a03a6: 'IonBlockSequence',
x300a03a8: 'IonControlPointSequence',
x300a03aa: 'IonWedgeSequence',
x300a03ac: 'IonWedgePositionSequence',
x300a0401: 'ReferencedSetupImageSequence',
x300a0402: 'SetupImageComment',
x300a0410: 'MotionSynchronizationSequence',
x300a0412: 'ControlPointOrientation',
x300a0420: 'GeneralAccessorySequence',
x300a0421: 'GeneralAccessoryID',
x300a0422: 'GeneralAccessoryDescription',
x300a0423: 'GeneralAccessoryType',
x300a0424: 'GeneralAccessoryNumber',
x300c0002: 'ReferencedRTPlanSequence',
x300c0004: 'ReferencedBeamSequence',
x300c0006: 'ReferencedBeamNumber',
x300c0007: 'ReferencedReferenceImageNumber',
x300c0008: 'StartCumulativeMetersetWeight',
x300c0009: 'EndCumulativeMetersetWeight',
x300c000a: 'ReferencedBrachyAppSetupSeq',
x300c000c: 'ReferencedBrachyAppSetupNumber',
x300c000e: 'ReferencedSourceNumber',
x300c0020: 'ReferencedFractionGroupSequence',
x300c0022: 'ReferencedFractionGroupNumber',
x300c0040: 'ReferencedVerificationImageSeq',
x300c0042: 'ReferencedReferenceImageSequence',
x300c0050: 'ReferencedDoseReferenceSequence',
x300c0051: 'ReferencedDoseReferenceNumber',
x300c0055: 'BrachyReferencedDoseReferenceSeq',
x300c0060: 'ReferencedStructureSetSequence',
x300c006a: 'ReferencedPatientSetupNumber',
x300c0080: 'ReferencedDoseSequence',
x300c00a0: 'ReferencedToleranceTableNumber',
x300c00b0: 'ReferencedBolusSequence',
x300c00c0: 'ReferencedWedgeNumber',
x300c00d0: 'ReferencedCompensatorNumber',
x300c00e0: 'ReferencedBlockNumber',
x300c00f0: 'ReferencedControlPointIndex',
x300c00f2: 'ReferencedControlPointSequence',
x300c00f4: 'ReferencedStartControlPointIndex',
x300c00f6: 'ReferencedStopControlPointIndex',
x300c0100: 'ReferencedRangeShifterNumber',
x300c0102: 'ReferencedLateralSpreadingDevNum',
x300c0104: 'ReferencedRangeModulatorNumber',
x300e0002: 'ApprovalStatus',
x300e0004: 'ReviewDate',
x300e0005: 'ReviewTime',
x300e0008: 'ReviewerName',
x40000000: 'TextGroupLength',
x40000010: 'Arbitrary',
x40004000: 'TextComments',
x40080040: 'ResultsID',
x40080042: 'ResultsIDIssuer',
x40080050: 'ReferencedInterpretationSequence',
x40080100: 'InterpretationRecordedDate',
x40080101: 'InterpretationRecordedTime',
x40080102: 'InterpretationRecorder',
x40080103: 'ReferenceToRecordedSound',
x40080108: 'InterpretationTranscriptionDate',
x40080109: 'InterpretationTranscriptionTime',
x4008010a: 'InterpretationTranscriber',
x4008010b: 'InterpretationText',
x4008010c: 'InterpretationAuthor',
x40080111: 'InterpretationApproverSequence',
x40080112: 'InterpretationApprovalDate',
x40080113: 'InterpretationApprovalTime',
x40080114: 'PhysicianApprovingInterpretation',
x40080115: 'InterpretationDiagnosisDescription',
x40080117: 'InterpretationDiagnosisCodeSeq',
x40080118: 'ResultsDistributionListSequence',
x40080119: 'DistributionName',
x4008011a: 'DistributionAddress',
x40080200: 'InterpretationID',
x40080202: 'InterpretationIDIssuer',
x40080210: 'InterpretationTypeID',
x40080212: 'InterpretationStatusID',
x40080300: 'Impressions',
x40084000: 'ResultsComments',
x4ffe0001: 'MACParametersSequence',
x50xx0005: 'CurveDimensions',
x50xx0010: 'NumberOfPoints',
x50xx0020: 'TypeOfData',
x50xx0022: 'CurveDescription',
x50xx0030: 'AxisUnits',
x50xx0040: 'AxisLabels',
x50xx0103: 'DataValueRepresentation',
x50xx0104: 'MinimumCoordinateValue',
x50xx0105: 'MaximumCoordinateValue',
x50xx0106: 'CurveRange',
x50xx0110: 'CurveDataDescriptor',
x50xx0112: 'CoordinateStartValue',
x50xx0114: 'CoordinateStepValue',
x50xx1001: 'CurveActivationLayer',
x50xx2000: 'AudioType',
x50xx2002: 'AudioSampleFormat',
x50xx2004: 'NumberOfChannels',
x50xx2006: 'NumberOfSamples',
x50xx2008: 'SampleRate',
x50xx200a: 'TotalTime',
x50xx200c: 'AudioSampleData',
x50xx200e: 'AudioComments',
x50xx2500: 'CurveLabel',
x50xx2600: 'CurveReferencedOverlaySequence',
x50xx2610: 'ReferencedOverlayGroup',
x50xx3000: 'CurveData',
x52009229: 'SharedFunctionalGroupsSequence',
x52009230: 'PerFrameFunctionalGroupsSequence',
x54000100: 'WaveformSequence',
x54000110: 'ChannelMinimumValue',
x54000112: 'ChannelMaximumValue',
x54001004: 'WaveformBitsAllocated',
x54001006: 'WaveformSampleInterpretation',
x5400100a: 'WaveformPaddingValue',
x54001010: 'WaveformData',
x56000010: 'FirstOrderPhaseCorrectionAngle',
x56000020: 'SpectroscopyData',
x60000000: 'OverlayGroupLength',
x60xx0010: 'OverlayRows',
x60xx0011: 'OverlayColumns',
x60xx0012: 'OverlayPlanes',
x60xx0015: 'NumberOfFramesInOverlay',
x60xx0022: 'OverlayDescription',
x60xx0040: 'OverlayType',
x60xx0045: 'OverlaySubtype',
x60xx0050: 'OverlayOrigin',
x60xx0051: 'ImageFrameOrigin',
x60xx0052: 'OverlayPlaneOrigin',
x60xx0060: 'OverlayCompressionCode',
x60xx0061: 'OverlayCompressionOriginator',
x60xx0062: 'OverlayCompressionLabel',
x60xx0063: 'OverlayCompressionDescription',
x60xx0066: 'OverlayCompressionStepPointers',
x60xx0068: 'OverlayRepeatInterval',
x60xx0069: 'OverlayBitsGrouped',
x60xx0100: 'OverlayBitsAllocated',
x60xx0102: 'OverlayBitPosition',
x60xx0110: 'OverlayFormat',
x60xx0200: 'OverlayLocation',
x60xx0800: 'OverlayCodeLabel',
x60xx0802: 'OverlayNumberOfTables',
x60xx0803: 'OverlayCodeTableLocation',
x60xx0804: 'OverlayBitsForCodeWord',
x60xx1001: 'OverlayActivationLayer',
x60xx1100: 'OverlayDescriptorGray',
x60xx1101: 'OverlayDescriptorRed',
x60xx1102: 'OverlayDescriptorGreen',
x60xx1103: 'OverlayDescriptorBlue',
x60xx1200: 'OverlaysGray',
x60xx1201: 'OverlaysRed',
x60xx1202: 'OverlaysGreen',
x60xx1203: 'OverlaysBlue',
x60xx1301: 'ROIArea',
x60xx1302: 'ROIMean',
x60xx1303: 'ROIStandardDeviation',
x60xx1500: 'OverlayLabel',
x60xx3000: 'OverlayData',
x60xx4000: 'OverlayComments',
x7fxx0000: 'PixelDataGroupLength',
x7fxx0010: 'PixelData',
x7fxx0011: 'VariableNextDataGroup',
x7fxx0020: 'VariableCoefficientsSDVN',
x7fxx0030: 'VariableCoefficientsSDHN',
x7fxx0040: 'VariableCoefficientsSDDN',
xfffafffa: 'DigitalSignaturesSequence',
xfffcfffc: 'DataSetTrailingPadding',
xfffee000: 'StartOfItem',
xfffee00d: 'EndOfItems',
xfffee0dd: 'EndOfSequence'
};
DICOMTagDescriptions.init(initialTagDescriptionMap); // Discard original map...
initialTagDescriptionMap = null;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"StackManager.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/StackManager.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
StackManager: function () {
return StackManager;
}
});
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
var getImageId;
module.watch(require("./getImageId"), {
getImageId: function (v) {
getImageId = v;
}
}, 1);
var OHIFError;
module.watch(require("./classes/OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 2);
var stackMap = {};
var configuration = {};
var stackUpdatedCallbacks = [];
/**
* Loop through the current series and add metadata to the
* Cornerstone meta data provider. This will be used to fill information
* into the viewport overlays, and to calculate reference lines and orientation markers
* @param {Object} stackMap stackMap object
* @param {Object} study Study object
* @param {Object} displaySet The set of images to make the stack from
* @return {Array} Array with image IDs
*/
function createAndAddStack(stackMap, study, displaySet) {
var metadataProvider = OHIF.viewer.metadataProvider;
var numImages = displaySet.images.length;
var imageIds = [];
var imageId;
displaySet.images.forEach(function (instance, imageIndex) {
var image = instance.getData();
var metaData = {
instance: image,
// in this context, instance will be the data of the InstanceMetadata object...
series: displaySet,
// TODO: Check this
study: study,
numImages: numImages,
imageIndex: imageIndex + 1
};
var numberOfFrames = image.numberOfFrames;
if (numberOfFrames > 1) {
OHIF.log.info('Multiframe image detected');
for (var i = 0; i < numberOfFrames; i++) {
metaData.frame = i;
imageId = getImageId(image, i);
imageIds.push(imageId);
metadataProvider.addMetadata(imageId, metaData);
}
} else {
imageId = getImageId(image);
imageIds.push(imageId);
metadataProvider.addMetadata(imageId, metaData);
}
});
var stack = {
displaySetInstanceUid: displaySet.displaySetInstanceUid,
imageIds: imageIds,
frameRate: displaySet.frameRate,
isClip: displaySet.isClip
};
stackMap[displaySet.displaySetInstanceUid] = stack;
return stack;
}
configuration = {
createAndAddStack: createAndAddStack
};
/**
* This object contains all the functions needed for interacting with the stack manager.
* Generally, findStack is the only function used. If you want to know when new stacks
* come in, you can register a callback with addStackUpdatedCallback.
*/
var StackManager = {
/**
* Removes all current stacks
*/
clearStacks: function () {
stackMap = {};
},
/**
* Create a stack from an image set, as well as add in the metadata on a per image bases.
* @param study The study who's metadata will be added
* @param displaySet The set of images to make the stack from
* @return {Array} Array with image IDs
*/
makeAndAddStack: function (study, displaySet) {
return configuration.createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks);
},
/**
* Find a stack from the currently created stacks.
* @param displaySetInstanceUid The UID of the stack to find.
* @returns {*} undefined if not found, otherwise the stack object is returned.
*/
findStack: function (displaySetInstanceUid) {
return stackMap[displaySetInstanceUid];
},
/**
* Find a stack or reate one if it has not been created yet
* @param study The study who's metadata will be added
* @param displaySet The set of images to make the stack from
* @return {Array} Array with image IDs
*/
findOrCreateStack: function (study, displaySet) {
var stack = this.findStack(displaySet.displaySetInstanceUid);
if (!stack || !stack.imageIds) {
stack = this.makeAndAddStack(study, displaySet);
}
return stack;
},
/**
* Gets the underlying map of displaySetInstanceUid to stack object.
* WARNING: Do not change this object. It directly affects the manager.
* @returns {{}} map of displaySetInstanceUid -> stack.
*/
getAllStacks: function () {
return stackMap;
},
/**
* Adds in a callback to be called on a stack being added / updated.
* @param callback must accept at minimum one argument,
* which is the stack that was added / updated.
*/
addStackUpdatedCallback: function (callback) {
if (typeof callback !== 'function') {
throw new OHIFError('callback must be provided as a function');
}
stackUpdatedCallbacks.push(callback);
},
/**
* Return configuration
*/
getConfiguration: function () {
return configuration;
},
/**
* Set configuration, in order to provide compatibility
* with other systems by overriding this functions
* @param {Object} config object with functions to be overrided
*
* For now, only makeAndAddStack can be overrided
*/
setConfiguration: function (config) {
configuration = config;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"WLPresets.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/WLPresets.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
WLPresets: function () {
return WLPresets;
}
});
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 1);
var Tracker;
module.watch(require("meteor/tracker"), {
Tracker: function (v) {
Tracker = v;
}
}, 2);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 3);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 4);
var cornerstone;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
}
}, 5);
var viewportUtils;
module.watch(require("./viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 6);
var WL_PRESET_CUSTOM = 'WL_PRESET_CUSTOM';
var WL_PRESET_DEFAULT = 'WL_PRESET_DEFAULT';
var WL_STORAGE_KEY = "WindowLevelPresetsDefinitions";
OHIF.viewer.defaultWLPresets = {
0: {
id: 'Soft Tissue',
wc: 40,
ww: 400
},
1: {
id: 'Lung',
wc: -600,
ww: 1500
},
2: {
id: 'Liver',
wc: 90,
ww: 150
},
3: {
id: 'Bone',
wc: 480,
ww: 2500
},
4: {
id: 'Brain',
wc: 40,
ww: 80
},
5: {},
6: {},
7: {},
8: {},
9: {}
};
var WindowLevelPresetsManager =
/*#__PURE__*/
function () {
function WindowLevelPresetsManager() {
this.defaults = {};
this.retrieveFunction = null;
this.storeFunction = null;
this.changeObserver = new Tracker.Dependency();
}
var _proto = WindowLevelPresetsManager.prototype;
_proto.setRetrieveFunction = function () {
function setRetrieveFunction(retrieveFunction) {
this.retrieveFunction = retrieveFunction;
}
return setRetrieveFunction;
}();
_proto.setStoreFunction = function () {
function setStoreFunction(storeFunction) {
this.storeFunction = storeFunction;
}
return setStoreFunction;
}();
/**
* Updates the enabledElement data for the Cornerstone element
* to reflect the current W/L preset which is applied.
*
* @param {HTMLElement} element
*/
_proto.updateElementWLPresetData = function () {
function updateElementWLPresetData(element) {
var wlPresetData = cornerstone.getElementData(element, 'wlPreset');
var enabledElement = cornerstone.getEnabledElement(element);
var viewport = enabledElement.viewport,
image = enabledElement.image;
var _viewport$voi = viewport.voi,
windowCenter = _viewport$voi.windowCenter,
windowWidth = _viewport$voi.windowWidth;
var presetName;
if (windowWidth === image.windowWidth && windowCenter === image.windowCenter) {
presetName = WL_PRESET_DEFAULT;
} else {
var _WLPresets = OHIF.viewer.wlPresets;
var currentPreset = Object.values(_WLPresets).find(function (currentPreset) {
return windowCenter === currentPreset.wc && windowWidth === currentPreset.ww;
});
if (currentPreset) {
presetName = currentPreset.id;
} else {
presetName = WL_PRESET_CUSTOM;
}
}
wlPresetData.name = presetName;
wlPresetData.ww = windowWidth;
wlPresetData.wc = windowCenter;
if (wlPresetData.name === WL_PRESET_CUSTOM) {
var custom = wlPresetData.custom || (wlPresetData.custom = Object.create(null));
custom.ww = windowWidth;
custom.wc = windowCenter;
}
}
return updateElementWLPresetData;
}();
/**
* Set specified W/L preset on given element on fallback to default W/L preset if the specified preset is not valid.
* @param {String} presetName The desired W/L preset to be applied
* @param {HTMLElement} element An enabled viewport DOM Element.
*/
_proto.applyWLPreset = function () {
function applyWLPreset(presetName, element) {
var wlPresets = OHIF.viewer.wlPresets;
var wlPresetData = cornerstone.getElementData(element, 'wlPreset');
var viewport = cornerstone.getViewport(element);
var preset = wlPresets[presetName] || _.findWhere(wlPresets, {
id: presetName
});
if (presetName === WL_PRESET_CUSTOM && wlPresetData.custom) {
viewport.voi.windowWidth = wlPresetData.custom.ww;
viewport.voi.windowCenter = wlPresetData.custom.wc;
} else if (preset && !_.isEmpty(preset) && preset.id) {
presetName = preset.id;
viewport.voi.windowWidth = preset.ww;
viewport.voi.windowCenter = preset.wc;
} else {
var enabledElement = cornerstone.getEnabledElement(element);
viewport.voi.windowWidth = enabledElement.image.windowWidth;
viewport.voi.windowCenter = enabledElement.image.windowCenter;
presetName = WL_PRESET_DEFAULT;
}
wlPresetData.name = presetName;
wlPresetData.ww = viewport.voi.windowWidth;
wlPresetData.wc = viewport.voi.windowCenter; // Update the viewport
cornerstone.setViewport(element, viewport); // Notify other components about W/L Preset changes
Session.set('OHIFWlPresetApplied', presetName);
}
return applyWLPreset;
}();
_proto.store = function () {
function store(wlPresets) {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.storeFunction) {
_this.storeFunction.call(_this, WL_STORAGE_KEY, wlPresets).then(resolve).catch(reject);
} else if (Meteor.userId()) {
OHIF.user.setData(WL_STORAGE_KEY, wlPresets).then(resolve).catch(reject);
} else {
Session.setPersistent(WL_STORAGE_KEY, wlPresets);
resolve();
}
}).then(function () {
return _this.setOHIFWLPresets.call(_this, wlPresets);
});
}
return store;
}();
_proto.retrieve = function () {
function retrieve() {
var _this2 = this;
return new Promise(function (resolve, reject) {
if (_this2.retrieveFunction) {
_this2.retrieveFunction.call(_this2).then(resolve).catch(reject);
} else if (OHIF.user) {
try {
resolve(OHIF.user.getData(WL_STORAGE_KEY));
} catch (error) {
reject(error);
}
} else {
resolve(Session.get(WL_STORAGE_KEY));
}
});
}
return retrieve;
}();
_proto.load = function () {
function load() {
var _this3 = this;
return new Promise(function (resolve, reject) {
_this3.retrieve().then(function (wlPresets) {
if (wlPresets) {
_this3.setOHIFWLPresets.call(_this3, wlPresets);
} else {
_this3.loadDefaults.call(_this3);
}
}).catch(function () {
return _this3.loadDefaults.call(_this3);
});
});
}
return load;
}();
_proto.applyWLPresetToActiveElement = function () {
function applyWLPresetToActiveElement(presetName) {
var element = viewportUtils.getActiveViewportElement();
if (!element) {
return;
}
this.applyWLPreset(presetName, element);
}
return applyWLPresetToActiveElement;
}();
/**
* Overrides OHIF's wlPresets
* @param {Object} wlPresets Object with wlPresets mapping
*/
_proto.setOHIFWLPresets = function () {
function setOHIFWLPresets(wlPresets) {
var hasOwn = Object.prototype.hasOwnProperty;
var presetMap = Object.create(null); // Objects without prototype have much faster lookup times
for (var index in meteorBabelHelpers.sanitizeForInObject(wlPresets)) {
if (hasOwn.call(wlPresets, index)) {
presetMap[index] = wlPresets[index];
}
}
OHIF.viewer.wlPresets = presetMap;
this.changeObserver.changed();
}
return setOHIFWLPresets;
}();
_proto.loadDefaults = function () {
function loadDefaults() {
this.setOHIFWLPresets(OHIF.viewer.defaultWLPresets);
}
return loadDefaults;
}();
_proto.resetDefaults = function () {
function resetDefaults() {
return this.store(OHIF.viewer.defaultWLPresets);
}
return resetDefaults;
}();
return WindowLevelPresetsManager;
}();
/**
* Export functions inside WLPresets namespace.
*/
var WLPresets = new WindowLevelPresetsManager();
Meteor.startup(function () {
WLPresets.loadDefaults();
WLPresets.load();
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"annotateTextUtils.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/annotateTextUtils.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
annotateTextUtils: function () {
return annotateTextUtils;
}
});
var viewportUtils;
module.watch(require("./viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 0);
var getTextCallback = function (doneChangingTextCallback) {
// This handles the text entry for the annotation tool
var keyPressHandler = function (e) {
// If Enter or Esc are pressed, close the dialog
if (e.which === 13 || e.which === 27) {
closeHandler();
}
};
var closeHandler = function () {
dialog.get(0).close();
doneChangingTextCallback(getTextInput.val()); // Reset the text value
getTextInput.val(''); // Reset the focus to the active viewport element
// This makes the mobile Safari keyboard close
var element = viewportUtils.getActiveViewportElement();
$(element).focus();
};
var dialog = $('#annotationDialog');
if (dialog.get(0).open === true) {
return;
}
var getTextInput = $('.annotationTextInput'); // Focus on the text input to open the Safari keyboard
getTextInput.focus();
dialog.get(0).showModal();
var confirm = dialog.find('.annotationDialogConfirm');
confirm.off('click');
confirm.on('click', function () {
closeHandler();
}); // Use keydown since keypress doesn't handle ESC in Chrome
dialog.off('keydown');
dialog.on('keydown', keyPressHandler);
};
var changeTextCallback = function (data, eventData, doneChangingTextCallback) {
var dialog = $('#relabelAnnotationDialog');
if (dialog.get(0).open === true) {
return;
} // Is necessary to use Blaze object to not create
// circular depencency with helper object (./helpers)
if (Blaze._globalHelpers.isTouchDevice()) {
// Center the dialog on screen on touch devices
dialog.css({
top: 0,
left: 0,
right: 0,
bottom: 0,
margin: 'auto'
});
} else {
// Place the dialog above the tool that is being relabelled
dialog.css({
top: eventData.currentPoints.page.y - dialog.outerHeight() - 20,
left: eventData.currentPoints.page.x - dialog.outerWidth() / 2
});
}
var getTextInput = dialog.find('.annotationTextInput');
var confirm = dialog.find('.relabelConfirm');
var remove = dialog.find('.relabelRemove');
getTextInput.val(data.text); // Focus on the text input to open the Safari keyboard
getTextInput.focus();
dialog.get(0).showModal();
confirm.off('click');
confirm.on('click', function () {
dialog.get(0).close();
doneChangingTextCallback(data, getTextInput.val());
}); // If the remove button is clicked, delete this marker
remove.off('click');
remove.on('click', function () {
dialog.get(0).close();
doneChangingTextCallback(data, undefined, true);
});
dialog.off('keydown');
dialog.on('keydown', keyPressHandler);
var keyPressHandler = function (e) {
// If Enter is pressed, close the dialog
if (e.which === 13) {
closeHandler();
}
};
var closeHandler = function () {
dialog.get(0).close();
doneChangingTextCallback(data, getTextInput.val()); // Reset the text value
getTextInput.val(''); // Reset the focus to the active viewport element
// This makes the mobile Safari keyboard close
var element = viewportUtils.getActiveViewportElement();
$(element).focus();
};
};
var annotateTextUtils = {
getTextCallback: getTextCallback,
changeTextCallback: changeTextCallback
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"createStacks.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/createStacks.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
createStacks: function () {
return createStacks;
}
});
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var ImageSet;
module.watch(require("./classes/ImageSet"), {
ImageSet: function (v) {
ImageSet = v;
}
}, 1);
var isImage;
module.watch(require("./isImage"), {
isImage: function (v) {
isImage = v;
}
}, 2);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 3);
var isMultiFrame = function (instance) {
// NumberOfFrames (0028,0008)
return instance.getRawValue('x00280008') > 1;
};
var makeDisplaySet = function (series, instances) {
var instance = instances[0];
var imageSet = new ImageSet(instances);
var seriesData = series.getData(); // set appropriate attributes to image set...
imageSet.setAttributes({
displaySetInstanceUid: imageSet.uid,
// create a local alias for the imageSet UID
seriesDate: seriesData.seriesDate,
seriesTime: seriesData.seriesTime,
seriesInstanceUid: series.getSeriesInstanceUID(),
seriesNumber: instance.getRawValue('x00200011'),
seriesDescription: instance.getRawValue('x0008103e'),
numImageFrames: instances.length,
frameRate: instance.getRawValue('x00181063'),
modality: instance.getRawValue('x00080060'),
isMultiFrame: isMultiFrame(instance)
}); // Sort the images in this series if needed
var shallSort = !OHIF.utils.ObjectPath.get(Meteor, 'settings.public.ui.sortSeriesByIncomingOrder');
if (shallSort) {
imageSet.sortBy(function (a, b) {
// Sort by InstanceNumber (0020,0013)
return (parseInt(a.getRawValue('x00200013', 0)) || 0) - (parseInt(b.getRawValue('x00200013', 0)) || 0);
});
} // Include the first image instance number (after sorted)
imageSet.setAttribute('instanceNumber', imageSet.getImage(0).getRawValue('x00200013'));
return imageSet;
};
var isSingleImageModality = function (modality) {
return modality === 'CR' || modality === 'MG' || modality === 'DX';
};
/**
* Creates a set of series to be placed in the Study Metadata
* The series that appear in the Study Metadata must represent
* imaging modalities.
*
* Furthermore, for drag/drop functionality,
* it is easiest if the stack objects also contain information about
* which study they are linked to.
*
* @param study The study instance metadata to be used
* @returns {Array} An array of series to be placed in the Study Metadata
*/
var createStacks = function (study) {
// Define an empty array of display sets
var displaySets = [];
if (!study || !study.getSeriesCount()) {
return displaySets;
} // Loop through the series (SeriesMetadata)
study.forEachSeries(function (series) {
// If the series has no instances, skip it
if (!series.getInstanceCount()) {
return;
} // Search through the instances (InstanceMedatada object) of this series
// Split Multi-frame instances and Single-image modalities
// into their own specific display sets. Place the rest of each
// series into another display set.
var stackableInstances = [];
series.forEachInstance(function (instance) {
// All imaging modalities must have a valid value for sopClassUid (x00080016) or rows (x00280010)
if (!isImage(instance.getRawValue('x00080016')) && !instance.getRawValue('x00280010')) {
return;
}
var displaySet;
if (isMultiFrame(instance)) {
displaySet = makeDisplaySet(series, [instance]);
displaySet.setAttributes({
isClip: true,
studyInstanceUid: study.getStudyInstanceUID(),
// Include the study instance Uid for drag/drop purposes
numImageFrames: instance.getRawValue('x00280008'),
// Override the default value of instances.length
instanceNumber: instance.getRawValue('x00200013'),
// Include the instance number
acquisitionDatetime: instance.getRawValue('x0008002a') // Include the acquisition datetime
});
displaySets.push(displaySet);
} else if (isSingleImageModality(instance.modality)) {
displaySet = makeDisplaySet(series, [instance]);
displaySet.setAttributes({
studyInstanceUid: study.getStudyInstanceUID(),
// Include the study instance Uid
instanceNumber: instance.getRawValue('x00200013'),
// Include the instance number
acquisitionDatetime: instance.getRawValue('x0008002a') // Include the acquisition datetime
});
displaySets.push(displaySet);
} else {
stackableInstances.push(instance);
}
});
if (stackableInstances.length) {
var displaySet = makeDisplaySet(series, stackableInstances);
displaySet.setAttribute('studyInstanceUid', study.getStudyInstanceUID());
displaySets.push(displaySet);
}
});
return displaySets;
};
/**
* Expose "createStacks"...
*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"crosshairsSynchronizers.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/crosshairsSynchronizers.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
crosshairsSynchronizers: function () {
return crosshairsSynchronizers;
}
});
var crosshairsSynchronizers = {
synchronizers: {}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"debugReactivity.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/debugReactivity.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
Meteor.startup(function () {
var debug = false;
if (debug === true) {
var logRenders = function () {
Object.keys(Template).forEach(function (name) {
if (name.indexOf('_') > -1) {
return;
}
var template = Template[name];
var oldRender = template.rendered;
var counter = 0;
template.rendered = function () {
console.log(name, 'render count: ', ++counter);
oldRender && oldRender.apply(this, arguments);
};
});
};
// http://www.meteorpedia.com/read/Debugging_Reactivity
Meteor.autorun(function (computation) {
computation.onInvalidate(function () {
console.trace();
});
});
var wrappedFind = Meteor.Collection.prototype.find;
Meteor.Collection.prototype.find = function () {
var cursor = wrappedFind.apply(this, arguments);
var collectionName = this._name || this._debugName;
/*cursor.observeChanges({
added: function(id, fields) {
console.log(collectionName, 'added', id, fields);
},
changed: function(id, fields) {
console.log(collectionName, 'changed', id, fields);
},
movedBefore: function(id, before) {
console.log(collectionName, 'movedBefore', id, before);
},
removed: function(id) {
console.log(collectionName, 'removed', id);
}
});*/
cursor.observe({
added: function (data) {
console.log(collectionName, 'added', data);
},
changed: function (data) {
console.log(collectionName, 'changed', data);
},
removed: function (data) {
console.log(collectionName, 'removed', data);
}
});
return cursor;
};
logRenders();
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"dialogUtils.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/dialogUtils.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
dialogUtils: function () {
return dialogUtils;
}
});
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 1);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 2);
var setFocusToActiveViewport;
module.watch(require("./setFocusToActiveViewport"), {
setFocusToActiveViewport: function (v) {
setFocusToActiveViewport = v;
}
}, 3);
var doneCallbackFunction;
/**
* Removes the backdrop abd closes opened dialog
* and focus to the active viewport. If a done callback is set,
* it's called before
* @param {Boolean} runCallback Indicate if callback function needs to be called. Default: true
*/
var closeHandler = function () {
var runCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
// Check if callback function exists
if (runCallback && typeof doneCallbackFunction === 'function') {
doneCallbackFunction();
} // Hide the lesion dialog
$('#confirmDeleteDialog').css('display', 'none'); // Remove the backdrop
$('.removableBackdrop').remove(); // Remove the callback
doneCallbackFunction = undefined; // Restore the focus to the active viewport
setFocusToActiveViewport();
};
/**
* Displays the confirmation dialog template and the removable backdrop element
*
* @param doneCallback A callback
* @param options
*/
var showConfirmDialog = function (doneCallback, options) {
// Show the backdrop
options = options || {};
Blaze.renderWithData(Template.removableBackdrop, options, document.body);
var confirmDeleteDialog = $('#confirmDeleteDialog');
confirmDeleteDialog.remove();
var viewer = document.getElementById('viewer');
Blaze.renderWithData(Template.confirmDeleteDialog, options, viewer); // Make sure the context menu is closed when the user clicks away
$('.removableBackdrop').one('mousedown touchstart', function () {
// Close dialog without calling callback
closeHandler(false);
});
confirmDeleteDialog = $('#confirmDeleteDialog');
confirmDeleteDialog.css('display', 'block');
confirmDeleteDialog.focus(); // If callback function is defined, save it for closeHandler
if (doneCallback && typeof doneCallback === 'function') {
doneCallbackFunction = doneCallback;
}
};
var dialogUtils = {
showConfirmDialog: showConfirmDialog,
closeHandler: closeHandler
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"displayReferenceLines.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/displayReferenceLines.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
displayReferenceLines: function () {
return displayReferenceLines;
}
});
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
function displayReferenceLines(element) {
// Check if image plane (orientation / loction) data is present for the current image
var enabledElement = cornerstone.getEnabledElement(element); // Check if element is already enabled and it's image was rendered
if (!enabledElement || !enabledElement.image) {
OHIF.log.info('displayReferenceLines enabled element is undefined or it\'s image is not rendered');
return;
}
var imageId = enabledElement.image.imageId;
var imagePlane = cornerstone.metaData.get('imagePlane', imageId); // Disable reference lines for the current element
cornerstoneTools.referenceLines.tool.disable(element);
if (!OHIF.viewer.refLinesEnabled || !imagePlane || !imagePlane.frameOfReferenceUID) {
OHIF.log.info('displayReferenceLines refLinesEnabled is not enabled, no imagePlane or no frameOfReferenceUID');
return;
}
OHIF.log.info("displayReferenceLines for image with id: " + imageId); // Loop through all other viewport elements and enable reference lines
$('.imageViewerViewport').not(element).each(function (index, viewportElement) {
var imageId;
if ($(viewportElement).find('canvas').length) {
try {
var _enabledElement = cornerstone.getEnabledElement(viewportElement);
imageId = _enabledElement.image.imageId;
} catch (error) {
return;
}
if (!imageId) {
return;
}
cornerstoneTools.referenceLines.tool.enable(viewportElement, OHIF.viewer.updateImageSynchronizer);
}
});
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"getElementIfNotEmpty.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/getElementIfNotEmpty.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
getElementIfNotEmpty: function () {
return getElementIfNotEmpty;
}
});
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 0);
function getElementIfNotEmpty(viewportIndex) {
// Meteor template helpers run more often than expected
// They often seem to run just before the whole template is rendered
// This meant that the onRendered event hadn't fired yet, so the
// element wasn't enabled / set empty yet. The check here
// for canvases under the 'enabled' element div is to prevent
// 'undefined' errors from the helper functions
var imageViewerViewports = $('.imageViewerViewport'),
element = imageViewerViewports.get(viewportIndex),
canvases = imageViewerViewports.eq(viewportIndex).find('canvas');
if (!element || $(element).hasClass('empty') || canvases.length === 0) {
return;
} // Check to make sure the element is enabled.
try {
var enabledElement = cornerstone.getEnabledElement(element);
} catch (error) {
return;
}
return element;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"getFrameOfReferenceUID.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/getFrameOfReferenceUID.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
getFrameOfReferenceUID: function () {
return getFrameOfReferenceUID;
}
});
function getFrameOfReferenceUID(element) {
var enabledElement;
try {
enabledElement = cornerstone.getEnabledElement(element);
} catch (error) {
return;
}
if (!enabledElement || !enabledElement.image) {
return;
}
var imageId = enabledElement.image.imageId;
var imagePlane = cornerstone.metaData.get('imagePlane', imageId);
if (!imagePlane || !imagePlane.frameOfReferenceUID) {
return;
}
return imagePlane.frameOfReferenceUID;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"getImageId.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/getImageId.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
getImageId: function () {
return getImageId;
}
});
var getWADORSImageId;
module.watch(require("./getWADORSImageId"), {
getWADORSImageId: function (v) {
getWADORSImageId = v;
}
}, 0);
// https://stackoverflow.com/a/6021027/3895126
function updateQueryStringParameter(uri, key, value) {
var regex = new RegExp('([?&])' + key + '=.*?(&|$)', 'i');
var separator = uri.indexOf('?') !== -1 ? '&' : '?';
if (uri.match(regex)) {
return uri.replace(regex, '$1' + key + '=' + value + '$2');
} else {
return uri + separator + key + '=' + value;
}
}
/**
* Obtain an imageId for Cornerstone from an image instance
*
* @param instance
* @param frame
* @param thumbnail
* @returns {string} The imageId to be used by Cornerstone
*/
function getImageId(instance, frame) {
var thumbnail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if (!instance) {
return;
}
if (typeof instance.getImageId === 'function') {
return instance.getImageId();
}
if (instance.url) {
if (frame !== undefined) {
instance.url = updateQueryStringParameter(instance.url, 'frame', frame);
}
return instance.url;
}
var renderingAttr = thumbnail ? 'thumbnailRendering' : 'imageRendering';
if (!instance[renderingAttr] || instance[renderingAttr] === 'wadouri' || !instance.wadorsuri) {
var imageId = 'dicomweb:' + instance.wadouri;
if (frame !== undefined) {
imageId += '&frame=' + frame;
}
return imageId;
} else {
return getWADORSImageId(instance, frame, thumbnail); // WADO-RS Retrieve Frame
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"getImageIdForImagePath.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/getImageIdForImagePath.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
module.export({
getImageIdForImagePath: function () {
return getImageIdForImagePath;
}
});
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
var getImageIdForImagePath = function (imagePath) {
var thumbnail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var _imagePath$split = imagePath.split('_'),
_imagePath$split2 = (0, _slicedToArray2.default)(_imagePath$split, 4),
studyInstanceUid = _imagePath$split2[0],
seriesInstanceUid = _imagePath$split2[1],
sopInstanceUid = _imagePath$split2[2],
frameIndex = _imagePath$split2[3];
var study = OHIF.viewer.Studies.findBy({
studyInstanceUid: studyInstanceUid
});
var studyMetadata = OHIF.viewerbase.getStudyMetadata(study);
var series = studyMetadata.getSeriesByUID(seriesInstanceUid);
var instance = series.getInstanceByUID(sopInstanceUid);
var imageId = OHIF.viewerbase.getImageId(instance, frameIndex, thumbnail);
return imageId;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"getStackDataIfNotEmpty.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/getStackDataIfNotEmpty.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
getStackDataIfNotEmpty: function () {
return getStackDataIfNotEmpty;
}
});
var getElementIfNotEmpty;
module.watch(require("./getElementIfNotEmpty.js"), {
getElementIfNotEmpty: function (v) {
getElementIfNotEmpty = v;
}
}, 0);
function getStackDataIfNotEmpty(viewportIndex) {
var element = getElementIfNotEmpty(viewportIndex);
if (!element) {
return;
}
var stackToolData = cornerstoneTools.getToolState(element, 'stack');
if (!stackToolData || !stackToolData.data || !stackToolData.data.length) {
return;
}
var stack = stackToolData.data[0];
if (!stack) {
return;
}
return stack;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"getStudyMetadata.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/getStudyMetadata.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
getStudyMetadata: function () {
return getStudyMetadata;
}
});
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
var getStudyMetadata = function (study) {
var studyMetadata = study;
if (study && !(studyMetadata instanceof OHIF.viewerbase.metadata.StudyMetadata)) {
studyMetadata = new OHIF.metadata.StudyMetadata(study, study.studyInstanceUid);
}
return studyMetadata;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"getWADORSImageId.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/getWADORSImageId.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
getWADORSImageId: function () {
return getWADORSImageId;
}
});
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
var getWADORSImageUrl;
module.watch(require("./getWADORSImageUrl"), {
getWADORSImageUrl: function (v) {
getWADORSImageUrl = v;
}
}, 1);
function getWADORSImageId(instance, frame) {
var uri = getWADORSImageUrl(instance, frame);
if (!uri) {
return;
}
var imageId = "wadors:" + uri;
OHIF.log.info('WADO-RS ImageID: ' + imageId);
return imageId;
}
;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"getWADORSImageUrl.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/getWADORSImageUrl.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
getWADORSImageUrl: function () {
return getWADORSImageUrl;
}
});
function getWADORSImageUrl(instance, frame) {
var wadorsuri = instance.wadorsuri;
if (!wadorsuri) {
return;
} // We need to sum 1 because WADO-RS frame number is 1-based
frame = (frame || 0) + 1; // Replaces /frame/1 by /frame/{frame}
wadorsuri = wadorsuri.replace(/(%2Fframes%2F)(\d+)/, "$1" + frame);
return wadorsuri;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"hotkeyUtils.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/hotkeyUtils.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
hotkeyUtils: function () {
return hotkeyUtils;
}
});
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 1);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 2);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 3);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 4);
var toolManager;
module.watch(require("./toolManager"), {
toolManager: function (v) {
toolManager = v;
}
}, 5);
var switchToImageRelative;
module.watch(require("./switchToImageRelative"), {
switchToImageRelative: function (v) {
switchToImageRelative = v;
}
}, 6);
var switchToImageByIndex;
module.watch(require("./switchToImageByIndex"), {
switchToImageByIndex: function (v) {
switchToImageByIndex = v;
}
}, 7);
var viewportUtils;
module.watch(require("./viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 8);
var panelNavigation;
module.watch(require("./panelNavigation"), {
panelNavigation: function (v) {
panelNavigation = v;
}
}, 9);
var WLPresets;
module.watch(require("./WLPresets"), {
WLPresets: function (v) {
WLPresets = v;
}
}, 10);
// TODO: add this to namespace definitions
Meteor.startup(function () {
OHIF.viewer.loadIndicatorDelay = 200;
OHIF.viewer.defaultTool = 'wwwc';
OHIF.viewer.refLinesEnabled = true;
OHIF.viewer.isPlaying = {};
OHIF.viewer.cine = {
framesPerSecond: 24,
loop: true
};
OHIF.viewer.defaultHotkeys = {
// Tool hotkeys
defaultTool: 'ESC',
zoom: 'Z',
wwwc: 'W',
pan: 'P',
angle: 'A',
stackScroll: 'S',
magnify: 'M',
length: '',
annotate: '',
dragProbe: '',
ellipticalRoi: '',
rectangleRoi: '',
// Viewport hotkeys
flipH: 'H',
flipV: 'V',
rotateR: 'R',
rotateL: 'L',
invert: 'I',
zoomIn: '',
zoomOut: '',
zoomToFit: '',
resetViewport: '',
clearTools: '',
// Viewport navigation hotkeys
scrollDown: 'DOWN',
scrollUp: 'UP',
scrollLastImage: 'END',
scrollFirstImage: 'HOME',
previousDisplaySet: 'PAGEUP',
nextDisplaySet: 'PAGEDOWN',
nextPanel: 'RIGHT',
previousPanel: 'LEFT',
// Miscellaneous hotkeys
toggleOverlayTags: 'O',
toggleCinePlay: 'SPACE',
toggleCineDialog: '',
toggleDownloadDialog: '',
// Preset hotkeys
WLPreset0: '1',
WLPreset1: '2',
WLPreset2: '3',
WLPreset3: '4',
WLPreset4: '5',
WLPreset5: '6',
WLPreset6: '7',
WLPreset7: '8',
WLPreset8: '9',
WLPreset9: '0'
}; // For now
OHIF.viewer.hotkeys = OHIF.viewer.defaultHotkeys; // Create commands context for viewer
var contextName = 'viewer';
OHIF.commands.createContext(contextName); // Create a function that returns true if the active viewport is empty
var isActiveViewportEmpty = function () {
var activeViewport = Session.get('activeViewport') || 0;
return $('.imageViewerViewport').eq(activeViewport).hasClass('empty');
}; // Functions to register the tool switching commands
var registerToolCommands = function (map) {
return _.each(map, function (commandName, toolId) {
OHIF.commands.register(contextName, toolId, {
name: commandName,
action: toolManager.setActiveTool,
params: toolId
});
});
}; // Register the default tool command
OHIF.commands.register(contextName, 'defaultTool', {
name: 'Default Tool',
action: function () {
return toolManager.setActiveTool(toolManager.getDefaultTool());
}
}); // Register the tool switching commands
registerToolCommands({
wwwc: 'W/L',
zoom: 'Zoom',
angle: 'Angle Measurement',
dragProbe: 'Pixel Probe',
ellipticalRoi: 'Elliptical ROI',
rectangleRoi: 'Rectangle ROI',
magnify: 'Magnify',
annotate: 'Annotate',
stackScroll: 'Scroll Stack',
pan: 'Pan',
length: 'Length Measurement',
wwwcRegion: 'W/L by Region',
crosshairs: 'Crosshairs'
}); // Functions to register the viewport commands
var registerViewportCommands = function (map) {
return _.each(map, function (commandName, commandId) {
OHIF.commands.register(contextName, commandId, {
name: commandName,
action: viewportUtils[commandId],
disabled: isActiveViewportEmpty
});
});
}; // Register the viewport commands
registerViewportCommands({
zoomIn: 'Zoom In',
zoomOut: 'Zoom Out',
zoomToFit: 'Zoom to Fit',
invert: 'Invert',
flipH: 'Flip Horizontally',
flipV: 'Flip Vertically',
rotateR: 'Rotate Right',
rotateL: 'Rotate Left',
resetViewport: 'Reset',
clearTools: 'Clear Tools'
}); // Register the preset switching commands
var applyPreset = function (presetName) {
return WLPresets.applyWLPresetToActiveElement(presetName);
};
for (var i = 0; i < 10; i++) {
OHIF.commands.register(contextName, "WLPreset" + i, {
name: "W/L Preset " + (i + 1),
action: applyPreset,
params: i
});
} // Check if display sets can be moved
var canMoveDisplaySets = function (isNext) {
if (!OHIF.viewerbase.layoutManager) {
return false;
} else {
return OHIF.viewerbase.layoutManager.canMoveDisplaySets(isNext);
}
}; // Register viewport navigation commands
OHIF.commands.set(contextName, {
scrollDown: {
name: 'Scroll Down',
action: function () {
return !isActiveViewportEmpty() && switchToImageRelative(1);
}
},
scrollUp: {
name: 'Scroll Up',
action: function () {
return !isActiveViewportEmpty() && switchToImageRelative(-1);
}
},
scrollFirstImage: {
name: 'Scroll to First Image',
action: function () {
return !isActiveViewportEmpty() && switchToImageByIndex(0);
}
},
scrollLastImage: {
name: 'Scroll to Last Image',
action: function () {
return !isActiveViewportEmpty() && switchToImageByIndex(-1);
}
},
previousDisplaySet: {
name: 'Previous Series',
action: function () {
return OHIF.viewerbase.layoutManager.moveDisplaySets(false);
},
disabled: function () {
return !canMoveDisplaySets(false);
}
},
nextDisplaySet: {
name: 'Next Series',
action: function () {
return OHIF.viewerbase.layoutManager.moveDisplaySets(true);
},
disabled: function () {
return !canMoveDisplaySets(true);
}
},
nextPanel: {
name: 'Next Panel',
action: function () {
return panelNavigation.loadNextActivePanel();
}
},
previousPanel: {
name: 'Previous Panel',
action: function () {
return panelNavigation.loadPreviousActivePanel();
}
}
}, true); // Register miscellaneous commands
OHIF.commands.set(contextName, {
toggleOverlayTags: {
name: 'Toggle Image Info Overlay',
action: function () {
var $dicomTags = $('.imageViewerViewportOverlay .dicomTag');
$dicomTags.toggle($dicomTags.eq(0).css('display') === 'none');
}
},
toggleCinePlay: {
name: 'Play/Pause Cine',
action: viewportUtils.toggleCinePlay,
disabled: OHIF.viewerbase.viewportUtils.hasMultipleFrames
},
toggleCineDialog: {
name: 'Show/Hide Cine Controls',
action: viewportUtils.toggleCineDialog,
disabled: OHIF.viewerbase.viewportUtils.hasMultipleFrames
},
toggleDownloadDialog: {
name: 'Show/Hide Download Dialog',
action: viewportUtils.toggleDownloadDialog,
disabled: function () {
return !viewportUtils.isDownloadEnabled();
}
}
}, true);
OHIF.viewer.hotkeyFunctions = {};
OHIF.viewer.loadedSeriesData = {}; // Enable hotkeys
hotkeyUtils.enableHotkeys();
}); // Define a jQuery reverse function
$.fn.reverse = [].reverse;
/**
* Overrides OHIF's refLinesEnabled
* @param {Boolean} refLinesEnabled True to enable and False to disable
*/
function setOHIFRefLines(refLinesEnabled) {
OHIF.viewer.refLinesEnabled = refLinesEnabled;
}
/**
* Overrides OHIF's hotkeys
* @param {Object} hotkeys Object with hotkeys mapping
*/
function setOHIFHotkeys(hotkeys) {
OHIF.viewer.hotkeys = hotkeys;
}
/**
* Binds all hotkeys keydown events to the tasks defined in
* OHIF.viewer.hotkeys or a given param
* @param {Object} hotkeys hotkey and task mapping (not required). If not given, uses OHIF.viewer.hotkeys
*/
function enableHotkeys(hotkeys) {
var definitions = hotkeys || OHIF.viewer.hotkeys;
OHIF.hotkeys.set('viewer', definitions, true);
OHIF.context.set('viewer');
}
/**
* Export functions inside hotkeyUtils namespace.
*/
var hotkeyUtils = {
setOHIFRefLines: setOHIFRefLines,
/* @TODO: find a better place for this... */
setOHIFHotkeys: setOHIFHotkeys,
enableHotkeys: enableHotkeys
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"imageViewerViewportData.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/imageViewerViewportData.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
imageViewerViewportData: function () {
return imageViewerViewportData;
}
});
var imageViewerViewportData = {
callbacks: {},
extendData: function () {// No-Op function...
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"instanceClassSpecificViewport.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/instanceClassSpecificViewport.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
getInstanceClassDefaultViewport: function () {
return getInstanceClassDefaultViewport;
},
setInstanceClassDefaultViewportFunction: function () {
return setInstanceClassDefaultViewportFunction;
}
});
var instanceClassViewportSettingsFunctions = {};
var getInstanceClassDefaultViewport = function (series, enabledElement, imageId) {
var instanceClass = series.sopClassUid;
if (!instanceClassViewportSettingsFunctions[instanceClass]) {
return;
}
return instanceClassViewportSettingsFunctions[instanceClass](series, enabledElement, imageId);
};
var setInstanceClassDefaultViewportFunction = function (instanceClass, fn) {
instanceClassViewportSettingsFunctions[instanceClass] = fn;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"isImage.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/isImage.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
isImage: function () {
return isImage;
}
});
var sopClassDictionary;
module.watch(require("./sopClassDictionary"), {
sopClassDictionary: function (v) {
sopClassDictionary = v;
}
}, 0);
function isImage(sopClassUid) {
if (sopClassUid === sopClassDictionary.ComputedRadiographyImageStorage || sopClassUid === sopClassDictionary.DigitalXRayImageStorageForPresentation || sopClassUid === sopClassDictionary.DigitalXRayImageStorageForProcessing || sopClassUid === sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation || sopClassUid === sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing || sopClassUid === sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation || sopClassUid === sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing || sopClassUid === sopClassDictionary.CTImageStorage || sopClassUid === sopClassDictionary.EnhancedCTImageStorage || sopClassUid === sopClassDictionary.LegacyConvertedEnhancedCTImageStorage || sopClassUid === sopClassDictionary.UltrasoundMultiframeImageStorage || sopClassUid === sopClassDictionary.MRImageStorage || sopClassUid === sopClassDictionary.EnhancedMRImageStorage || sopClassUid === sopClassDictionary.EnhancedMRColorImageStorage || sopClassUid === sopClassDictionary.LegacyConvertedEnhancedMRImageStorage || sopClassUid === sopClassDictionary.UltrasoundImageStorage || sopClassUid === sopClassDictionary.SecondaryCaptureImageStorage || sopClassUid === sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage || sopClassUid === sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage || sopClassUid === sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage || sopClassUid === sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage || sopClassUid === sopClassDictionary.XRayAngiographicImageStorage || sopClassUid === sopClassDictionary.EnhancedXAImageStorage || sopClassUid === sopClassDictionary.XRayRadiofluoroscopicImageStorage || sopClassUid === sopClassDictionary.EnhancedXRFImageStorage || sopClassUid === sopClassDictionary.XRay3DAngiographicImageStorage || sopClassUid === sopClassDictionary.XRay3DCraniofacialImageStorage || sopClassUid === sopClassDictionary.BreastTomosynthesisImageStorage || sopClassUid === sopClassDictionary.BreastProjectionXRayImageStorageForPresentation || sopClassUid === sopClassDictionary.BreastProjectionXRayImageStorageForProcessing || sopClassUid === sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation || sopClassUid === sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing || sopClassUid === sopClassDictionary.NuclearMedicineImageStorage || sopClassUid === sopClassDictionary.VLEndoscopicImageStorage || sopClassUid === sopClassDictionary.VideoEndoscopicImageStorage || sopClassUid === sopClassDictionary.VLMicroscopicImageStorage || sopClassUid === sopClassDictionary.VideoMicroscopicImageStorage || sopClassUid === sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage || sopClassUid === sopClassDictionary.VLPhotographicImageStorage || sopClassUid === sopClassDictionary.VideoPhotographicImageStorage || sopClassUid === sopClassDictionary.OphthalmicPhotography8BitImageStorage || sopClassUid === sopClassDictionary.OphthalmicPhotography16BitImageStorage || sopClassUid === sopClassDictionary.OphthalmicTomographyImageStorage || sopClassUid === sopClassDictionary.VLWholeSlideMicroscopyImageStorage || sopClassUid === sopClassDictionary.PositronEmissionTomographyImageStorage || sopClassUid === sopClassDictionary.EnhancedPETImageStorage || sopClassUid === sopClassDictionary.LegacyConvertedEnhancedPETImageStorage || sopClassUid === sopClassDictionary.RTImageStorage) {
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"panelNavigation.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/panelNavigation.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
panelNavigation: function () {
return panelNavigation;
}
});
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 0);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 1);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 2);
var setActiveViewport;
module.watch(require("./setActiveViewport"), {
setActiveViewport: function (v) {
setActiveViewport = v;
}
}, 3);
var loadPreviousActivePanel = function () {
OHIF.log.info('nextActivePanel');
var currentIndex = Session.get('activeViewport');
currentIndex--;
var $viewports = $('.viewportContainer');
var numViewports = $viewports.length;
if (currentIndex < 0) {
currentIndex = numViewports - 1;
}
var viewportContainer = $viewports.get(currentIndex);
if (!viewportContainer) {
return;
}
setActiveViewport(viewportContainer);
};
var loadNextActivePanel = function () {
OHIF.log.info('nextActivePanel');
var currentIndex = Session.get('activeViewport');
currentIndex++;
var $viewports = $('.viewportContainer');
var numViewports = $viewports.length;
if (currentIndex >= numViewports) {
currentIndex = 0;
}
var viewportContainer = $viewports.get(currentIndex);
if (!viewportContainer) {
return;
}
setActiveViewport(viewportContainer);
};
/**
* Export functions inside panelNavigation namespace.
*/
var panelNavigation = {
loadPreviousActivePanel: loadPreviousActivePanel,
loadNextActivePanel: loadNextActivePanel
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"prepareViewerData.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/prepareViewerData.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
prepareViewerData: function () {
return prepareViewerData;
}
});
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 0);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 1);
var prepareViewerData = function (_ref) {
var studyInstanceUids = _ref.studyInstanceUids,
seriesInstanceUids = _ref.seriesInstanceUids,
timepointId = _ref.timepointId,
_ref$timepointsFilter = _ref.timepointsFilter,
timepointsFilter = _ref$timepointsFilter === void 0 ? {} : _ref$timepointsFilter;
// Clear the cornerstone tool data to sync the measurements with the measurements API
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState({}); // Retrieve the studies metadata
var promise = new Promise(function (resolve, reject) {
var processData = function (viewerData) {
OHIF.studies.retrieveStudiesMetadata(viewerData.studyInstanceUids, viewerData.seriesInstanceUids).then(function (studies) {
// Add additional metadata to our study from the studylist
studies.forEach(function (study) {
var studylistStudy = OHIF.studylist.collections.Studies.findOne({
studyInstanceUid: study.studyInstanceUid
});
if (!studylistStudy) {
return;
}
Object.assign(study, studylistStudy);
});
resolve({
studies: studies,
viewerData: viewerData
});
}).catch(reject);
}; // Check if the studies are already given and ignore the timepoint ID if so
if (studyInstanceUids && studyInstanceUids.length) {
var viewerData = {
studyInstanceUids: studyInstanceUids,
seriesInstanceUids: seriesInstanceUids
};
processData(viewerData);
} else {
// Find the timepoint by ID and load the studies from it
OHIF.studylist.timepointApi.retrieveTimepoints(timepointsFilter).then(function () {
var viewerData = buildViewerDataFromTimepointId(timepointId);
processData(viewerData);
}).catch(reject);
}
});
return promise;
};
var buildViewerDataFromTimepointId = function (timepointId) {
var timepoint = OHIF.studylist.timepointApi.timepoints.findOne({
timepointId: timepointId
});
if (!timepoint) {
throw new Error('Unable to find a time point with the given ID');
} // Get the relevant studyInstanceUids given the timepoints
var data = getDataFromTimepoint(timepoint);
if (!data.studyInstanceUids) {
throw new Error('No studies found that are related to this timepoint');
} // Build the viewer data and return it
return Object.assign(data, {
currentTimepointId: timepointId
});
};
/**
* Retrieves related studies given a Baseline or Follow-up Timepoint
*
* @param {Object} timepoint A document from the Timepoints Collection
* @returns {Object} An object containing the related studies UIDs and timepoint IDs
*/
var getDataFromTimepoint = function (timepoint) {
var relatedStudies = _.clone(timepoint.studyInstanceUids); // If this is the baseline, we should stop here and return the relevant studies
if (isBaseline(timepoint)) {
return {
studyInstanceUids: relatedStudies,
timepointIds: [timepoint.timepointId]
};
} // Otherwise, this is a follow-up exam, so we should also find the baseline timepoint,
// and all studies related to it. We also enforce that the Baseline should have a studyDate
// prior to the latest studyDate in the current (Follow-up) Timepoint.
var Timepoints = OHIF.studylist.timepointApi.timepoints;
var baseline = Timepoints.findOne({
timepointType: 'baseline',
patientId: timepoint.patientId,
latestDate: {
$lte: timepoint.latestDate
}
});
var timepointIds = [];
if (baseline) {
relatedStudies = relatedStudies.concat(baseline.studyInstanceUids);
timepointIds.push(baseline.timepointId);
} else {
OHIF.log.warn('No Baseline found while opening a Follow-up Timepoint');
}
var priorFilter = {
latestDate: {
$lt: timepoint.latestDate
}
};
var priorSorting = {
sort: {
latestDate: -1
}
};
var prior = OHIF.studylist.timepointApi.timepoints.findOne(priorFilter, priorSorting);
if (prior && prior.timepointId !== baseline.timepointId) {
relatedStudies = relatedStudies.concat(prior.studyInstanceUids);
timepointIds.push(prior.timepointId);
}
relatedStudies = _.uniq(relatedStudies);
timepointIds.push(timepoint.timepointId);
return {
studyInstanceUids: relatedStudies,
timepointIds: timepointIds
};
};
/**
* Checks if a Timepoints is a baseline or not
*
* @param {Object} timepoint A document from the Timepoints Collection
* @returns {boolean} Whether or not the timepoint is stored as a Baseline
*/
var isBaseline = function (timepoint) {
return timepoint.timepointType === 'baseline';
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"renderViewer.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/renderViewer.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
renderViewer: function () {
return renderViewer;
}
});
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
var renderViewer = function (context, params) {
var layoutTemplate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'app';
// Wait until the viewer data is ready to render it
var promise = OHIF.viewerbase.prepareViewerData(params); // Show loading state while preparing the viewer data
OHIF.ui.showDialog('dialogLoading', {
promise: promise
}); // Render the viewer when the data is ready
promise.then(function (_ref) {
var studies = _ref.studies,
viewerData = _ref.viewerData;
OHIF.viewer.data = viewerData;
context.render(layoutTemplate, {
data: {
template: 'viewer',
studies: studies
}
});
}).catch(function (error) {
context.render(layoutTemplate, {
data: {
template: 'errorText',
error: error
}
});
});
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"setActiveViewport.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/setActiveViewport.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
setActiveViewport: function () {
return setActiveViewport;
}
});
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 0);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 1);
var Random;
module.watch(require("meteor/random"), {
Random: function (v) {
Random = v;
}
}, 2);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 3);
var StudyPrefetcher;
module.watch(require("./classes/StudyPrefetcher"), {
StudyPrefetcher: function (v) {
StudyPrefetcher = v;
}
}, 4);
var displayReferenceLines;
module.watch(require("./displayReferenceLines"), {
displayReferenceLines: function (v) {
displayReferenceLines = v;
}
}, 5);
var PLUGIN_CORNERSTONE = 'cornerstone';
/**
* Sets a viewport element active
* @param {node} element DOM element to be activated or viewportIndex
*/
function setActiveViewport(element) {
var $viewports = $('.viewportContainer');
var viewportIndex = $viewports.index(element);
var $element = $viewports.eq(viewportIndex);
if (!$element.length) {
OHIF.log.info('setActiveViewport element does not exist');
return;
}
OHIF.log.info("setActiveViewport setting viewport index: " + viewportIndex); // If viewport is not active
if (!$element.parents('.viewportContainer').hasClass('active')) {
// Trigger an event for compatibility with other systems
$element.trigger('OHIFBeforeActivateViewport');
} // When an OHIFActivateViewport event is fired, update the Meteor Session
// with the viewport index that it was fired from.
Session.set('activeViewport', viewportIndex); // Finally, enable stack prefetching and hide the reference lines from
// the newly activated viewport that has a canvas
var layoutManager = OHIF.viewerbase.layoutManager;
var viewportData = layoutManager.viewportData[viewportIndex];
if (viewportData.plugin === PLUGIN_CORNERSTONE && $element.find('canvas').length) {
// Cornerstone Tools compare DOM elements (check getEnabledElement cornerstone function)
// so we can't pass a jQuery object as an argument, otherwise it throws an excepetion
var domElement = $element.find('.imageViewerViewport').get(0);
displayReferenceLines(domElement);
StudyPrefetcher.getInstance().prefetch(); // @TODO Add this to OHIFAfterActivateViewport handler...
var synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer;
if (!synchronizer) {
return;
}
synchronizer.update();
} // Set the div to focused, so keypress events are handled
//$(element).focus();
//.focus() event breaks in FF&IE
$element.triggerHandler('focus'); // Trigger OHIFAfterActivateViewport event on activated instance
// for compatibility with other systems
$element.trigger('OHIFAfterActivateViewport');
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"setFocusToActiveViewport.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/setFocusToActiveViewport.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
setFocusToActiveViewport: function () {
return setFocusToActiveViewport;
}
});
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 0);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 1);
/**
* Restores the browser focus to the currently specified active viewport
* as determined from Meteor's Session variable.
*
* This is allows keydown events to be captured on the focused element.
*/
var setFocusToActiveViewport = function () {
// Get the list of viewports
var viewports = $('.imageViewerViewport'); // Get the current active viewport index from Session
var activeViewportIndex = Session.get('activeViewport'); // Find the div from the list of viewports
var activeViewport = viewports.eq(activeViewportIndex); // Set the browser focus to this div
activeViewport.focus();
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"sopClassDictionary.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/sopClassDictionary.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
sopClassDictionary: function () {
return sopClassDictionary;
}
});
var sopClassDictionary = {
ComputedRadiographyImageStorage: "1.2.840.10008.5.1.4.1.1.1",
DigitalXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.1",
DigitalXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.1.1",
DigitalMammographyXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.2",
DigitalMammographyXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.2.1",
DigitalIntraOralXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.3",
DigitalIntraOralXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.3.1",
CTImageStorage: "1.2.840.10008.5.1.4.1.1.2",
EnhancedCTImageStorage: "1.2.840.10008.5.1.4.1.1.2.1",
LegacyConvertedEnhancedCTImageStorage: "1.2.840.10008.5.1.4.1.1.2.2",
UltrasoundMultiframeImageStorage: "1.2.840.10008.5.1.4.1.1.3.1",
MRImageStorage: "1.2.840.10008.5.1.4.1.1.4",
EnhancedMRImageStorage: "1.2.840.10008.5.1.4.1.1.4.1",
MRSpectroscopyStorage: "1.2.840.10008.5.1.4.1.1.4.2",
EnhancedMRColorImageStorage: "1.2.840.10008.5.1.4.1.1.4.3",
LegacyConvertedEnhancedMRImageStorage: "1.2.840.10008.5.1.4.1.1.4.4",
UltrasoundImageStorage: "1.2.840.10008.5.1.4.1.1.6.1",
EnhancedUSVolumeStorage: "1.2.840.10008.5.1.4.1.1.6.2",
SecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7",
MultiframeSingleBitSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.1",
MultiframeGrayscaleByteSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.2",
MultiframeGrayscaleWordSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.3",
MultiframeTrueColorSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.4",
Sop12LeadECGWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.1.1",
GeneralECGWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.1.2",
AmbulatoryECGWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.1.3",
HemodynamicWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.2.1",
CardiacElectrophysiologyWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.3.1",
BasicVoiceAudioWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.4.1",
GeneralAudioWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.4.2",
ArterialPulseWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.5.1",
RespiratoryWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.6.1",
GrayscaleSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.1",
ColorSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.2",
PseudoColorSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.3",
BlendingSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.4",
XAXRFGrayscaleSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.5",
XRayAngiographicImageStorage: "1.2.840.10008.5.1.4.1.1.12.1",
EnhancedXAImageStorage: "1.2.840.10008.5.1.4.1.1.12.1.1",
XRayRadiofluoroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.12.2",
EnhancedXRFImageStorage: "1.2.840.10008.5.1.4.1.1.12.2.1",
XRay3DAngiographicImageStorage: "1.2.840.10008.5.1.4.1.1.13.1.1",
XRay3DCraniofacialImageStorage: "1.2.840.10008.5.1.4.1.1.13.1.2",
BreastTomosynthesisImageStorage: "1.2.840.10008.5.1.4.1.1.13.1.3",
BreastProjectionXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.13.1.4",
BreastProjectionXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.13.1.5",
IntravascularOpticalCoherenceTomographyImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.14.1",
IntravascularOpticalCoherenceTomographyImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.14.2",
NuclearMedicineImageStorage: "1.2.840.10008.5.1.4.1.1.20",
RawDataStorage: "1.2.840.10008.5.1.4.1.1.66",
SpatialRegistrationStorage: "1.2.840.10008.5.1.4.1.1.66.1",
SpatialFiducialsStorage: "1.2.840.10008.5.1.4.1.1.66.2",
DeformableSpatialRegistrationStorage: "1.2.840.10008.5.1.4.1.1.66.3",
SegmentationStorage: "1.2.840.10008.5.1.4.1.1.66.4",
SurfaceSegmentationStorage: "1.2.840.10008.5.1.4.1.1.66.5",
RealWorldValueMappingStorage: "1.2.840.10008.5.1.4.1.1.67",
SurfaceScanMeshStorage: "1.2.840.10008.5.1.4.1.1.68.1",
SurfaceScanPointCloudStorage: "1.2.840.10008.5.1.4.1.1.68.2",
VLEndoscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.1",
VideoEndoscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.1.1",
VLMicroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.2",
VideoMicroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.2.1",
VLSlideCoordinatesMicroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.3",
VLPhotographicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.4",
VideoPhotographicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.4.1",
OphthalmicPhotography8BitImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.1",
OphthalmicPhotography16BitImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.2",
StereometricRelationshipStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.3",
OphthalmicTomographyImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.4",
VLWholeSlideMicroscopyImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.6",
LensometryMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.1",
AutorefractionMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.2",
KeratometryMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.3",
SubjectiveRefractionMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.4",
VisualAcuityMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.5",
SpectaclePrescriptionReportStorage: "1.2.840.10008.5.1.4.1.1.78.6",
OphthalmicAxialMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.7",
IntraocularLensCalculationsStorage: "1.2.840.10008.5.1.4.1.1.78.8",
MacularGridThicknessandVolumeReport: "1.2.840.10008.5.1.4.1.1.79.1",
OphthalmicVisualFieldStaticPerimetryMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.80.1",
OphthalmicThicknessMapStorage: "1.2.840.10008.5.1.4.1.1.81.1",
CornealTopographyMapStorage: "1.2.840.10008.5.1.4.1.1.82.1",
BasicTextSR: "1.2.840.10008.5.1.4.1.1.88.11",
EnhancedSR: "1.2.840.10008.5.1.4.1.1.88.22",
ComprehensiveSR: "1.2.840.10008.5.1.4.1.1.88.33",
Comprehensive3DSR: "1.2.840.10008.5.1.4.1.1.88.34",
ProcedureLog: "1.2.840.10008.5.1.4.1.1.88.40",
MammographyCADSR: "1.2.840.10008.5.1.4.1.1.88.50",
KeyObjectSelection: "1.2.840.10008.5.1.4.1.1.88.59",
ChestCADSR: "1.2.840.10008.5.1.4.1.1.88.65",
XRayRadiationDoseSR: "1.2.840.10008.5.1.4.1.1.88.67",
RadiopharmaceuticalRadiationDoseSR: "1.2.840.10008.5.1.4.1.1.88.68",
ColonCADSR: "1.2.840.10008.5.1.4.1.1.88.69",
ImplantationPlanSRDocumentStorage: "1.2.840.10008.5.1.4.1.1.88.70",
EncapsulatedPDFStorage: "1.2.840.10008.5.1.4.1.1.104.1",
EncapsulatedCDAStorage: "1.2.840.10008.5.1.4.1.1.104.2",
PositronEmissionTomographyImageStorage: "1.2.840.10008.5.1.4.1.1.128",
EnhancedPETImageStorage: "1.2.840.10008.5.1.4.1.1.130",
LegacyConvertedEnhancedPETImageStorage: "1.2.840.10008.5.1.4.1.1.128.1",
BasicStructuredDisplayStorage: "1.2.840.10008.5.1.4.1.1.131",
RTImageStorage: "1.2.840.10008.5.1.4.1.1.481.1",
RTDoseStorage: "1.2.840.10008.5.1.4.1.1.481.2",
RTStructureSetStorage: "1.2.840.10008.5.1.4.1.1.481.3",
RTBeamsTreatmentRecordStorage: "1.2.840.10008.5.1.4.1.1.481.4",
RTPlanStorage: "1.2.840.10008.5.1.4.1.1.481.5",
RTBrachyTreatmentRecordStorage: "1.2.840.10008.5.1.4.1.1.481.6",
RTTreatmentSummaryRecordStorage: "1.2.840.10008.5.1.4.1.1.481.7",
RTIonPlanStorage: "1.2.840.10008.5.1.4.1.1.481.8",
RTIonBeamsTreatmentRecordStorage: "1.2.840.10008.5.1.4.1.1.481.9",
RTBeamsDeliveryInstructionStorage: "1.2.840.10008.5.1.4.34.7",
GenericImplantTemplateStorage: "1.2.840.10008.5.1.4.43.1",
ImplantAssemblyTemplateStorage: "1.2.840.10008.5.1.4.44.1",
ImplantTemplateGroupStorage: "1.2.840.10008.5.1.4.45.1"
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"sortStudy.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/sortStudy.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
sortStudy: function () {
return sortStudy;
}
});
var OHIFError;
module.watch(require("./classes/OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 0);
function sortStudy(study) {
if (!study || !study.seriesList) {
throw new OHIFError('Insufficient study data was provided to sortStudy');
}
study.seriesList.sort(function (a, b) {
return a.seriesNumber - b.seriesNumber;
});
study.seriesList.forEach(function (series) {
series.instances.sort(function (a, b) {
return a.instanceNumber - b.instanceNumber;
});
});
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"sortingManager.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/sortingManager.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
sortingManager: function () {
return sortingManager;
}
});
var createStacks;
module.watch(require("./createStacks"), {
createStacks: function (v) {
createStacks = v;
}
}, 0);
var getDisplaySets = function (studyMetadata, seriesNumber, iteratorFunction) {
var iteratorFn = typeof iteratorFunction !== 'function' ? createStacks : iteratorFunction;
return iteratorFn(studyMetadata, seriesNumber);
};
var sortingManager = {
getDisplaySets: getDisplaySets
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"switchToImageByIndex.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/switchToImageByIndex.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
switchToImageByIndex: function () {
return switchToImageByIndex;
}
});
var viewportUtils;
module.watch(require("./viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 0);
function switchToImageByIndex(newImageIdIndex) {
var element = viewportUtils.getActiveViewportElement();
cornerstoneTools.scrollToIndex(element, newImageIdIndex);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"switchToImageRelative.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/switchToImageRelative.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
switchToImageRelative: function () {
return switchToImageRelative;
}
});
var viewportUtils;
module.watch(require("./viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 0);
function switchToImageRelative(distanceFromCurrentIndex) {
var element = viewportUtils.getActiveViewportElement();
cornerstoneTools.scroll(element, distanceFromCurrentIndex);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"textMarkerUtils.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/textMarkerUtils.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
textMarkerUtils: function () {
return textMarkerUtils;
}
});
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
var toolManager;
module.watch(require("./toolManager"), {
toolManager: function (v) {
toolManager = v;
}
}, 1);
var viewportUtils;
module.watch(require("./viewportUtils"), {
viewportUtils: function (v) {
viewportUtils = v;
}
}, 2);
var changeTextCallback = function (data, eventData, doneChangingTextCallback) {
// This handles the double-click/long-press event on Spine text marker labels
var keyPressHandler = function (e) {
// If Enter or Esc are pressed, close the dialog
if (e.which === 13 || e.which === 27) {
closeHandler();
}
}; // Deactivate textMarker tool after editing a spine label & if spine is not active tool
var deactivateAfterEdit = function () {
if (toolManager.getActiveTool() !== 'spine') {
var element = viewportUtils.getActiveViewportElement();
cornerstoneTools.textMarker.deactivate(element, 1);
}
};
var closeHandler = function () {
dialog.get(0).close();
doneChangingTextCallback(data, select.val());
deactivateAfterEdit(); // Reset the focus to the active viewport element
// This makes the mobile Safari keyboard close
var element = viewportUtils.getActiveViewportElement();
$(element).focus();
};
var dialog = $('#textMarkerRelabelDialog'); // Is necessary to use Blaze object to not create
// circular depencency with helper object (./helpers)
if (Blaze._globalHelpers.isTouchDevice()) {
// Center the dialog on screen on touch devices
dialog.css({
top: 0,
left: 0,
right: 0,
bottom: 0,
margin: 'auto'
});
dialog.find('.dialog.arrow').hide();
} else {
// Place the dialog above the tool that is being relabelled
// TODO = Switch this to the tool coordinates, but put back into
// page coordinates.
dialog.css({
top: eventData.currentPoints.page.y - dialog.outerHeight() - 20,
left: eventData.currentPoints.page.x - dialog.outerWidth() / 2
});
dialog.find('.dialog.arrow').show();
}
var select = dialog.find('.relabelSelect');
var confirm = dialog.find('.relabelConfirm');
var remove = dialog.find('.relabelRemove'); // If the remove button is clicked, delete this marker
remove.off('click');
remove.on('click', function () {
dialog.get(0).close();
doneChangingTextCallback(data, undefined, true);
deactivateAfterEdit();
});
dialog.get(0).showModal();
$('.relabelSelect').val(data.text).trigger('change'); //Update selector to the current
confirm.off('click');
confirm.on('click', function () {
closeHandler();
}); // Use keydown since keypress doesn't handle ESC in Chrome
dialog.off('keydown');
dialog.on('keydown', keyPressHandler);
};
var textMarkerUtils = {
changeTextCallback: changeTextCallback
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"thumbnailDragHandlers.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/thumbnailDragHandlers.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
thumbnailDragHandlers: function () {
return thumbnailDragHandlers;
}
});
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 0);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 1);
var cloneElement = function (element, targetId) {
// Clone the DOM element
var clone = element.cloneNode(true); // Find any canvas children to clone
var clonedCanvases = $(clone).find('canvas');
clonedCanvases.each(function (canvasIndex, clonedCanvas) {
// Draw from the original canvas to the cloned canvas
var context = clonedCanvas.getContext('2d');
var thumbnailCanvas = $(element).find('canvas').get(canvasIndex);
context.drawImage(thumbnailCanvas, 0, 0);
}); // Update the clone with the targetId
clone.id = targetId;
clone.style.visibility = 'hidden';
return clone;
};
var thumbnailDragStartHandler = function (event, data) {
// Prevent any scrolling behaviour normally caused by the original event
event.originalEvent.preventDefault(); // Identify the current study and series index from the thumbnail's DOM position
var targetThumbnail = event.currentTarget;
var $imageThumbnail = $(targetThumbnail); // Force to hardware acceleration to move element
// if browser supports translate property
var useTransform = OHIF.ui.styleProperty.check('transform', 'translate(1px, 1px)'); // Clone the image thumbnail
var targetId = 'DragClone';
var clone = cloneElement(targetThumbnail, targetId);
var $clone = $(clone);
$clone.addClass('imageThumbnailClone'); // Set pointerEvents to pass through the clone DOM element
// This is necessary in order to identify what is below it
// when using document.elementFromPoint
clone.style.pointerEvents = 'none'; // Append the clone to the body
document.body.appendChild(clone); // Set the cursor x and y positions from the current touch/mouse coordinates
var cursorX;
var cursorY; // Handle touchStart cases
if (event.type === 'touchstart') {
cursorX = event.originalEvent.touches[0].pageX;
cursorY = event.originalEvent.touches[0].pageY;
} else {
cursorX = event.pageX;
cursorY = event.pageY; // Also hook up event handlers for mouse events
var handlers = {};
handlers.mousemove = function (event) {
return thumbnailDragHandler(event);
};
handlers.mouseup = function (event) {
return thumbnailDragEndHandler(event, data, handlers);
};
$(document).on('mousemove', handlers.mousemove);
$(document).on('mouseup', handlers.mouseup);
} // This block gets the current offset of the touch/mouse
// relative to the window
//
// i.e. Where did the user grab it from?
var offset = $imageThumbnail.offset();
var left = offset.left,
top = offset.top; // This difference is saved for later so the element movement looks normal
var diff = {
x: cursorX - left,
y: cursorY - top
};
$clone.data('diff', diff);
$clone.css({
visibility: 'hidden',
'z-index': 100000
}); // This sets the default style properties of the cloned element so it is
// ready to be dragged around the page
if (useTransform) {
var viewerHeight = $('#viewer').height();
var headerHeight = $('.header').outerHeight();
var heightDiff = viewerHeight + headerHeight; // Save height difference for later to set top position of the element during movement
$clone.data('heightDiff', heightDiff);
var positionX = cursorX - diff.x;
var positionY = cursorY - diff.y - heightDiff;
var translation = "translate(" + positionX + "px, " + positionY + "px)";
OHIF.ui.styleProperty.set($clone.get(0), 'transform', translation);
} else {
$clone.css({
left: cursorX - diff.x,
position: 'fixed',
top: cursorY - diff.y
});
}
};
var thumbnailDragHandler = function (event) {
// Get the touch/mouse coordinates from the event
var cursorX;
var cursorY;
if (event.type === 'touchmove') {
cursorX = event.originalEvent.changedTouches[0].pageX;
cursorY = event.originalEvent.changedTouches[0].pageY;
} else {
cursorX = event.pageX;
cursorY = event.pageY;
} // Find the clone element and update it's position on the page
var $clone = $('#DragClone');
var diff = $clone.data('diff'); // Force to hardware acceleration to move element
// if browser supports translate property
var useTransform = OHIF.ui.styleProperty.check('transform', 'translate(1px, 1px)');
$clone.css({
visibility: 'visible',
'z-index': 100000
}); // This sets the default style properties of the cloned element so it is
// ready to be dragged around the page
if (useTransform) {
var heightDiff = $clone.data('heightDiff');
var positionX = cursorX - diff.x;
var positionY = cursorY - diff.y - heightDiff;
var translation = "translate(" + positionX + "px, " + positionY + "px)";
OHIF.ui.styleProperty.set($clone.get(0), 'transform', translation);
} else {
$clone.css({
left: cursorX - diff.x,
position: 'fixed',
top: cursorY - diff.y
});
} // Identify the element below the current cursor position
var elemBelow = document.elementFromPoint(cursorX, cursorY); // If none exists, stop here
if (!elemBelow) {
return;
} // Remove any current faded effects on viewports
$('.viewportContainer canvas').removeClass('faded'); // Figure out what to do depending on what we're dragging over
var $viewportsDraggedOver = $(elemBelow).parents('.viewportContainer');
if ($viewportsDraggedOver.length) {
// If we're dragging over a non-empty viewport, fade it and change the cursor style
$viewportsDraggedOver.find('canvas').not('.magnifyTool').addClass('faded');
document.body.style.cursor = 'copy';
} else if (elemBelow.classList.contains('viewportContainer') && elemBelow.classList.contains('empty')) {
// If we're dragging over an empty viewport, just change the cursor style
document.body.style.cursor = 'copy';
} else {
// Otherwise, keep the cursor as no-drop style
document.body.style.cursor = 'no-drop';
}
};
var thumbnailDragEndHandler = function (event, data, handlers) {
// Remove the mouse event listeners
if (handlers) {
$(document).off('mousemove', handlers.mousemove);
$(document).off('mouseup', handlers.mouseup);
} // Reset the cursor style to the default
document.body.style.cursor = 'auto'; // Get the cloned element
var $clone = $('#DragClone'); // If it doesn't exist, stop here
if (!$clone.length) {
return;
}
var offset = $clone.offset();
var top = offset.top,
left = offset.left;
var diff = $clone.data('diff'); // Identify the element below the cloned element position
var elemBelow = document.elementFromPoint(left + diff.x, top + diff.y); // Remove all cloned elements from the page
$('.imageThumbnailClone').remove(); // Remove any current faded effects on viewports
$('.viewportContainer canvas').removeClass('faded'); // If none exists, stop here
if (!elemBelow) {
return;
} // Remove any fade effects on the element below
elemBelow.classList.remove('faded');
var element;
var $viewportsDraggedOver = $(elemBelow).closest('.viewportContainer');
if ($viewportsDraggedOver.length) {
// If we're dragging over a non-empty viewport, retrieve it
element = $viewportsDraggedOver.get(0);
} else if (elemBelow.classList.contains('viewportContainer') && elemBelow.classList.contains('empty')) {
// If we're dragging over an empty viewport, retrieve that instead
element = elemBelow;
} else {
// Otherwise, stop here
return false;
} // If there is no stored drag and drop data, stop here
if (!data) {
return false;
} // Get the dropped viewport index
var viewportIndex = $('.viewportContainer').index(element); // Rerender the viewport using the dragged thumbnail data
OHIF.viewerbase.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, data);
return false;
};
var thumbnailDragHandlers = {
thumbnailDragEndHandler: thumbnailDragEndHandler,
thumbnailDragStartHandler: thumbnailDragStartHandler,
thumbnailDragHandler: thumbnailDragHandler
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"toolManager.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/toolManager.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
toolManager: function () {
return toolManager;
}
});
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 1);
var Random;
module.watch(require("meteor/random"), {
Random: function (v) {
Random = v;
}
}, 2);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 3);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 4);
var cornerstone, cornerstoneTools;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
},
cornerstoneTools: function (v) {
cornerstoneTools = v;
}
}, 5);
var getFrameOfReferenceUID;
module.watch(require("./getFrameOfReferenceUID"), {
getFrameOfReferenceUID: function (v) {
getFrameOfReferenceUID = v;
}
}, 6);
var updateCrosshairsSynchronizer;
module.watch(require("./updateCrosshairsSynchronizer"), {
updateCrosshairsSynchronizer: function (v) {
updateCrosshairsSynchronizer = v;
}
}, 7);
var crosshairsSynchronizers;
module.watch(require("./crosshairsSynchronizers"), {
crosshairsSynchronizers: function (v) {
crosshairsSynchronizers = v;
}
}, 8);
var annotateTextUtils;
module.watch(require("./annotateTextUtils"), {
annotateTextUtils: function (v) {
annotateTextUtils = v;
}
}, 9);
var textMarkerUtils;
module.watch(require("./textMarkerUtils"), {
textMarkerUtils: function (v) {
textMarkerUtils = v;
}
}, 10);
var isTouchDevice;
module.watch(require("./helpers/isTouchDevice"), {
isTouchDevice: function (v) {
isTouchDevice = v;
}
}, 11);
var defaultTool = {
left: 'wwwc',
right: 'zoom',
middle: 'pan'
};
var activeTool;
var defaultMouseButtonTools;
var tools = {};
var gestures = {
zoomTouchPinch: {
enabled: true
},
panMultiTouch: {
enabled: true,
numPointers: 2
},
stackScrollMultiTouch: {
enabled: true,
numPointers: 3
},
doubleTapZoom: {
enabled: true
}
};
var toolDefaultStates = {
activate: [],
deactivate: ['length', 'angle', 'annotate', 'ellipticalRoi', 'rectangleRoi', 'spine'],
enable: [],
disable: [],
disabledToolButtons: [],
shadowConfig: {
shadow: false,
shadowColor: '#000000',
shadowOffsetX: 0,
shadowOffsetY: 0
},
textBoxConfig: {
centering: {
x: true,
y: true
}
}
};
var initialized = false;
/**
* Exported "toolManager" Singleton
*/
var toolManager = {
init: function () {
toolManager.addTool('wwwc', {
mouse: cornerstoneTools.wwwc,
touch: cornerstoneTools.wwwcTouchDrag
});
toolManager.addTool('zoom', {
mouse: cornerstoneTools.zoom,
touch: cornerstoneTools.zoomTouchDrag
});
toolManager.addTool('wwwcRegion', {
mouse: cornerstoneTools.wwwcRegion,
touch: cornerstoneTools.wwwcRegionTouch
});
toolManager.addTool('dragProbe', {
mouse: cornerstoneTools.dragProbe,
touch: cornerstoneTools.dragProbeTouch
});
toolManager.addTool('pan', {
mouse: cornerstoneTools.pan,
touch: cornerstoneTools.panTouchDrag,
multiTouch: cornerstoneTools.panMultiTouch
});
toolManager.addTool('stackScroll', {
mouse: cornerstoneTools.stackScroll,
touch: cornerstoneTools.stackScrollTouchDrag,
multiTouch: cornerstoneTools.stackScrollMultiTouch
});
toolManager.addTool('length', {
mouse: cornerstoneTools.length,
touch: cornerstoneTools.lengthTouch
});
toolManager.addTool('angle', {
mouse: cornerstoneTools.simpleAngle,
touch: cornerstoneTools.simpleAngleTouch
});
toolManager.addTool('magnify', {
mouse: cornerstoneTools.magnify,
touch: cornerstoneTools.magnifyTouchDrag
});
toolManager.addTool('ellipticalRoi', {
mouse: cornerstoneTools.ellipticalRoi,
touch: cornerstoneTools.ellipticalRoiTouch
});
toolManager.addTool('rectangleRoi', {
mouse: cornerstoneTools.rectangleRoi,
touch: cornerstoneTools.rectangleRoiTouch
});
toolManager.addTool('annotate', {
mouse: cornerstoneTools.arrowAnnotate,
touch: cornerstoneTools.arrowAnnotateTouch
});
toolManager.addTool('rotate', {
mouse: cornerstoneTools.rotate,
touch: cornerstoneTools.rotateTouchDrag
});
toolManager.addTool('spine', {
mouse: cornerstoneTools.textMarker,
touch: cornerstoneTools.textMarkerTouch
});
toolManager.addTool('crosshairs', {
mouse: cornerstoneTools.crosshairs,
touch: cornerstoneTools.crosshairsTouch
});
toolManager.addTool('scaleOverlayTool', {
mouse: cornerstoneTools.scaleOverlayTool
}); // if a default tool is globally defined, make it the default tool...
if (OHIF.viewer.defaultTool) {
this.setDefaultTool(OHIF.viewer.defaultTool);
}
defaultMouseButtonTools = Meteor.settings && Meteor.settings.public && Meteor.settings.public.defaultMouseButtonTools; // Override default tool if defined in settings
if (defaultMouseButtonTools) {
if (defaultMouseButtonTools.left) {
this.setDefaultTool(defaultMouseButtonTools.left);
}
if (defaultMouseButtonTools.right) {
this.setDefaultTool(defaultMouseButtonTools.right, 'right');
}
if (defaultMouseButtonTools.middle) {
this.setDefaultTool(defaultMouseButtonTools.middle, 'middle');
}
}
this.configureTools();
initialized = true;
},
configureTools: function () {
// Get Cornerstone Tools
var _cornerstoneTools = cornerstoneTools,
textStyle = _cornerstoneTools.textStyle,
toolStyle = _cornerstoneTools.toolStyle,
toolColors = _cornerstoneTools.toolColors,
length = _cornerstoneTools.length,
arrowAnnotate = _cornerstoneTools.arrowAnnotate,
zoom = _cornerstoneTools.zoom,
ellipticalRoi = _cornerstoneTools.ellipticalRoi,
textMarker = _cornerstoneTools.textMarker,
magnify = _cornerstoneTools.magnify; // Set text box background color
textStyle.setBackgroundColor('transparent'); // Set the tool font and font size
// context.font = "[style] [variant] [weight] [size]/[line height] [font family]";
var fontFamily = 'Roboto, OpenSans, HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif';
textStyle.setFont('15px ' + fontFamily); // Set the tool width
toolStyle.setToolWidth(2); // Set color for inactive tools
toolColors.setToolColor('rgb(255, 255, 0)'); // yellow
// Set color for active tools
toolColors.setActiveColor('rgb(50, 205, 50)'); // limegreen
// Set shadow configuration
var shadowConfig = toolManager.getToolDefaultStates().shadowConfig; // Get some tools config to not override them
var lengthConfig = length.getConfiguration();
var ellipticalRoiConfig = ellipticalRoi.getConfiguration(); // Add shadow to length tool
length.setConfiguration(Object.assign({}, lengthConfig, shadowConfig, {
drawHandlesOnHover: true
})); // Add shadow to length tool
ellipticalRoi.setConfiguration(Object.assign({}, ellipticalRoiConfig, shadowConfig)); // Set the configuration values for the Text Marker (Spine Labelling) tool
var $startFrom = $('#startFrom');
var $ascending = $('#ascending');
var textMarkerConfig = {
markers: ['L5', 'L4', 'L3', 'L2', 'L1', // Lumbar spine
'T12', 'T11', 'T10', 'T9', 'T8', 'T7', // Thoracic spine
'T6', 'T5', 'T4', 'T3', 'T2', 'T1', 'C7', 'C6', 'C5', 'C4', 'C3', 'C2', 'C1'],
current: $startFrom.val(),
ascending: $ascending.is(':checked'),
loop: true,
changeTextCallback: textMarkerUtils.changeTextCallback,
shadow: shadowConfig.shadow,
shadowColor: shadowConfig.shadowColor,
shadowOffsetX: shadowConfig.shadowOffsetX,
shadowOffsetY: shadowConfig.shadowOffsetY
};
textMarker.setConfiguration(textMarkerConfig); // Set the configuration values for the text annotation (Arrow) tool
var annotateConfig = {
getTextCallback: annotateTextUtils.getTextCallback,
changeTextCallback: annotateTextUtils.changeTextCallback,
drawHandles: false,
arrowFirst: true
};
arrowAnnotate.setConfiguration(annotateConfig);
var zoomConfig = {
minScale: 0.05,
maxScale: 10
};
zoom.setConfiguration(zoomConfig);
var magnifyConfig = {
magnifySize: 300,
magnificationLevel: 3
};
magnify.setConfiguration(magnifyConfig);
if (Meteor.settings && Meteor.settings.public && Meteor.settings.public.defaultGestures) {
gestures.zoomTouchPinch = Meteor.settings.public.defaultGestures.zoomTouchPinch || gestures.zoomTouchPinch;
gestures.stackScrollMultiTouch = Meteor.settings.public.defaultGestures.stackScrollMultiTouch || gestures.stackScrollMultiTouch;
gestures.panMultiTouch = Meteor.settings.public.defaultGestures.panMultiTouch || gestures.panMultiTouch;
gestures.doubleTapZoom = Meteor.settings.public.defaultGestures.doubleTapZoom || gestures.doubleTapZoom;
} // Set number of fingers to stack scroll
if (gestures.stackScrollMultiTouch.enabled === true && gestures.stackScrollMultiTouch.numPointers) {
var stackScrollMultiTouchConfig = {
testPointers: function (eventData) {
return eventData.numPointers === gestures.stackScrollMultiTouch.numPointers;
}
};
cornerstoneTools.stackScrollMultiTouch.setConfiguration(stackScrollMultiTouchConfig);
} // Set number of fingers to pan
if (gestures.panMultiTouch.enabled === true && gestures.panMultiTouch.numPointers) {
var panMultiTouchConfig = {
testPointers: function (eventData) {
return eventData.numPointers === gestures.panMultiTouch.numPointers;
}
};
cornerstoneTools.panMultiTouch.setConfiguration(panMultiTouchConfig);
}
},
/**
* This function searches an object to return the keys that contain a specific value
*
* @param object {object} The object to be searched
* @param value The value to be found
*
* @returns {array} The keys for which the object has the specified value
*/
getKeysByValue: function (object, value) {
// http://stackoverflow.com/questions/9907419/javascript-object-get-key-by-value
return Object.keys(object).filter(function (key) {
return object[key] === value;
});
},
configureLoadProcess: function () {
// Whenever CornerstoneImageLoadProgress is fired, identify which viewports
// the "in-progress" image is to be displayed in. Then pass the percent complete
// via the Meteor Session to the other templates to be displayed in the relevant viewports.
function handleLoadProgress(e) {
var eventData = e.detail;
var viewportIndices = toolManager.getKeysByValue(window.ViewportLoading, eventData.imageId);
viewportIndices.forEach(function (viewportIndex) {
Session.set('CornerstoneLoadProgress' + viewportIndex, eventData.percentComplete);
});
var encodedId = OHIF.string.encodeId(eventData.imageId);
Session.set('CornerstoneThumbnailLoadProgress' + encodedId, eventData.percentComplete);
}
cornerstone.events.removeEventListener('cornerstoneimageloadprogress', handleLoadProgress);
cornerstone.events.addEventListener('cornerstoneimageloadprogress', handleLoadProgress);
},
setGestures: function (newGestures) {
gestures = newGestures;
},
getGestures: function () {
return gestures;
},
addTool: function (name, base) {
tools[name] = base;
},
getTools: function () {
return tools;
},
setToolDefaultStates: function (states) {
toolDefaultStates = states;
},
getToolDefaultStates: function () {
return toolDefaultStates;
},
setActiveToolForElement: function (toolId, element, button) {
var canvases = $(element).find('canvas');
if (element.classList.contains('empty') || !canvases.length) {
return;
} // If button is not defined, we should consider it left
if (!button) {
button = 'left';
} // First, deactivate the current active tool
tools[activeTool.left].mouse.deactivate(element, 1); // 1 means left mouse button
tools[activeTool.middle].mouse.deactivate(element, 2); // 2 means middle mouse button
tools[activeTool.right].mouse.deactivate(element, 4); // 3 means right mouse button
if (tools[activeTool.left].touch) {
tools[activeTool.left].touch.deactivate(element);
}
if (tools[activeTool.right].multiTouch) {
tools[activeTool.right].multiTouch.disable(element);
} // Enable tools based on their default states
Object.keys(toolDefaultStates).forEach(function (action) {
var relevantTools = toolDefaultStates[action];
if (!relevantTools || !relevantTools.length || action === 'disabledToolButtons') return;
relevantTools.forEach(function (toolType) {
// the currently active tool has already been deactivated and can be skipped
if (action === 'deactivate' && (toolType === activeTool.left || toolType === activeTool.middle || toolType === activeTool.right)) {
return;
}
tools[toolType].mouse[action](element, action === 'activate' || action === 'deactivate' ? 1 : void 0);
if (tools[toolType].touch) {
tools[toolType].touch[action](element);
}
if (tools[toolType].multiTouch) {
tools[toolType].multiTouch[action](element);
}
});
}); // Get the stack toolData
var toolData = cornerstoneTools.getToolState(element, 'stack');
if (!toolData || !toolData.data || !toolData.data.length) {
return;
} // Get the imageIds for this element
var imageIds = toolData.data[0].imageIds; // Get the mouse button tools
var newToolIdLeft = activeTool.left;
if (button === 'left') {
newToolIdLeft = toolId;
}
var newCornerstoneToolLeft = tools[newToolIdLeft]; // left mouse tool is used for touch as well
var newToolIdMiddle = activeTool.middle;
if (button === 'middle') {
newToolIdMiddle = toolId;
}
var newCornerstoneToolMiddle = cornerstoneTools[newToolIdMiddle];
var newToolIdRight = activeTool.right;
if (button === 'right') {
newToolIdRight = toolId;
}
var newCornerstoneToolRight = tools[newToolIdRight]; // right mouse tool is used for multi-touch as well
// Deactivate scroll wheel tools
cornerstoneTools.zoomWheel.deactivate(element);
cornerstoneTools.stackScrollWheel.deactivate(element);
cornerstoneTools.panMultiTouch.disable(element);
cornerstoneTools.zoomTouchPinch.disable(element);
cornerstoneTools.stackScrollMultiTouch.disable(element);
cornerstoneTools.doubleTapZoom.disable(element); // Reactivate the relevant scrollwheel tool for this element
if (imageIds.length > 1) {
// scroll is the default tool for middle mouse wheel for stacks
cornerstoneTools.stackScrollWheel.activate(element); // 3 or more finger stack scroll
if (gestures.stackScrollMultiTouch.enabled === true && gestures.stackScrollMultiTouch.numPointers >= 3) {
var stackScrollMultiTouchConfig = {
testPointers: function (eventData) {
return eventData.numPointers === gestures.stackScrollMultiTouch.numPointers;
}
};
cornerstoneTools.stackScrollMultiTouch.setConfiguration(stackScrollMultiTouchConfig);
cornerstoneTools.stackScrollMultiTouch.activate(element);
}
} else {
// zoom is the default tool for middle mouse wheel for single images (non stacks)
cornerstoneTools.zoomWheel.activate(element);
} // 3 or more finger pan
if (gestures.panMultiTouch.enabled === true && gestures.panMultiTouch.numPointers >= 3) {
var panMultiTouchConfig = {
testPointers: function (eventData) {
return eventData.numPointers === gestures.panMultiTouch.numPointers;
}
};
cornerstoneTools.panMultiTouch.setConfiguration(panMultiTouchConfig);
cornerstoneTools.panMultiTouch.activate(element);
} // TODO: Remove this messy approach for adding synchronizer when necessary.
var leftToolSynchronizer;
if (newToolIdLeft === 'crosshairs') {
var currentFrameOfReferenceUID = getFrameOfReferenceUID(element);
if (currentFrameOfReferenceUID) {
updateCrosshairsSynchronizer(currentFrameOfReferenceUID);
leftToolSynchronizer = crosshairsSynchronizers.synchronizers[currentFrameOfReferenceUID];
}
if (newToolIdLeft === newToolIdMiddle && newToolIdMiddle === newToolIdRight) {
newCornerstoneToolRight.mouse.activate(element, 7); // 7 means left mouse button, right mouse button and middle mouse button
} else if (newToolIdLeft === newToolIdMiddle) {
newCornerstoneToolMiddle.activate(element, 3); // 3 means left mouse button and middle mouse button
newCornerstoneToolRight.mouse.activate(element, 4); // 4 means right mouse button
} else if (newToolIdMiddle === newToolIdRight) {
newCornerstoneToolRight.mouse.activate(element, 6); // 6 means right mouse button and middle mouse button
newCornerstoneToolLeft.mouse.activate(element, 1, leftToolSynchronizer); // 1 means left mouse button
} else if (newToolIdLeft === newToolIdRight) {
newCornerstoneToolMiddle.activate(element, 2); // 2 means middle mouse button
newCornerstoneToolRight.mouse.activate(element, 5); // 5 means left mouse button and right mouse button
} else {
newCornerstoneToolLeft.mouse.activate(element, 1, leftToolSynchronizer); // 1 means left mouse button
newCornerstoneToolMiddle.activate(element, 2); // 2 means middle mouse button
newCornerstoneToolRight.mouse.activate(element, 4); // 4 means right mouse button
}
} else {
// This block ensures that all mouse button tools keep working
if (newToolIdLeft === newToolIdMiddle && newToolIdMiddle === newToolIdRight) {
newCornerstoneToolRight.mouse.activate(element, 7); // 7 means left mouse button, right mouse button and middle mouse button
} else if (newToolIdLeft === newToolIdMiddle) {
newCornerstoneToolMiddle.activate(element, 3); // 3 means left mouse button and middle mouse button
newCornerstoneToolRight.mouse.activate(element, 4); // 4 means right mouse button
} else if (newToolIdMiddle === newToolIdRight) {
newCornerstoneToolRight.mouse.activate(element, 6); // 6 means right mouse button and middle mouse button
newCornerstoneToolLeft.mouse.activate(element, 1); // 1 means left mouse button
} else if (newToolIdLeft === newToolIdRight) {
newCornerstoneToolMiddle.activate(element, 2); // 2 means middle mouse button
newCornerstoneToolRight.mouse.activate(element, 5); // 5 means left mouse button and right mouse button
} else {
setTimeout(function () {
return newCornerstoneToolLeft.mouse.activate(element, 1);
}); // >>>> TODO Find out why it's working only with a timeout
// newCornerstoneToolLeft.mouse.activate(element, 1); // 1 means left mouse button
newCornerstoneToolMiddle.activate(element, 2); // 2 means middle mouse button
newCornerstoneToolRight.mouse.activate(element, 4); // 4 means right mouse button
}
} // One finger touch
if (newCornerstoneToolLeft.touch) {
if (leftToolSynchronizer) {
newCornerstoneToolLeft.touch.activate(element, leftToolSynchronizer);
} else {
newCornerstoneToolLeft.touch.activate(element);
}
} // Two finger swipe
var twoFingerMultiTouchConfig = {
testPointers: function (eventData) {
return eventData.numPointers === 2;
}
};
if (newCornerstoneToolRight.multiTouch) {
newCornerstoneToolRight.multiTouch.setConfiguration(twoFingerMultiTouchConfig);
newCornerstoneToolRight.multiTouch.activate(element);
} else if (gestures.panMultiTouch.enabled === true && gestures.panMultiTouch.numPointers === 2) {
cornerstoneTools.panMultiTouch.setConfiguration(twoFingerMultiTouchConfig);
cornerstoneTools.panMultiTouch.activate(element);
} else if (gestures.stackScrollMultiTouch.enabled === true && gestures.stackScrollMultiTouch.numPointers === 2) {
cornerstoneTools.stackScrollMultiTouch.setConfiguration(twoFingerMultiTouchConfig);
cornerstoneTools.stackScrollMultiTouch.activate(element);
} // Two finger pinch
if (gestures.zoomTouchPinch.enabled === true) {
cornerstoneTools.zoomTouchPinch.activate(element);
} // Double Tap
if (gestures.doubleTapZoom.enabled === true) {
cornerstoneTools.doubleTapZoom.activate(element);
}
},
setActiveTool: function (toolId, elements, button) {
if (!initialized) {
toolManager.init();
}
var $elements;
if (!elements || !elements.length) {
$elements = $('.imageViewerViewport');
} else {
$elements = $(elements);
}
var checkElementEnabled = function (allElementsEnabled, element) {
try {
cornerstone.getEnabledElement(element);
return allElementsEnabled;
} catch (error) {
return true;
}
};
if (!activeTool) {
activeTool = defaultTool;
} // If button is not defined, we should consider it left
if (!button) {
button = 'left';
}
var activeToolId = activeTool[button];
/**
* TODO: Add textMarkerDialogs template to OHIF's
*/
var dialog = document.getElementById('textMarkerOptionsDialog');
if (dialog) {
if (toolId === 'spine' && activeToolId !== 'spine' && dialog.getAttribute('open') !== 'open') {
dialog.show();
} else if (activeToolId !== 'spine' && dialog.getAttribute('open') === 'open') {
dialog.close();
}
}
if (!toolId) {
toolId = this.getDefaultTool(button);
} // Otherwise, set the active tool for all viewport elements
$elements.each(function (index, element) {
if (checkElementEnabled(element) === false) {
return;
}
toolManager.setActiveToolForElement(toolId, element, button);
});
activeTool[button] = toolId; // Enable reactivity
Session.set('ToolManagerActiveToolUpdated', Random.id());
},
getNearbyToolData: function (element, coords, toolTypes) {
var allTools = this.getTools();
var touchDevice = isTouchDevice();
var nearbyTool = {};
var pointNearTool = false;
toolTypes.forEach(function (toolType) {
var toolData = cornerstoneTools.getToolState(element, toolType);
if (!toolData) {
return;
}
toolData.data.forEach(function (data, index) {
var toolInterfaceName = toolType;
var toolInterface; // Edge cases where the tool is not the same as the typeName
if (toolType === 'simpleAngle') {
toolInterfaceName = 'angle';
} else if (toolType === 'arrowAnnotate') {
toolInterfaceName = 'annotate';
}
if (touchDevice) {
toolInterface = allTools[toolInterfaceName].touch;
} else {
toolInterface = allTools[toolInterfaceName].mouse;
}
if (toolInterface.pointNearTool(element, data, coords)) {
pointNearTool = true;
nearbyTool.tool = data;
nearbyTool.index = index;
nearbyTool.toolType = toolType;
}
});
if (pointNearTool) {
return false;
}
});
return pointNearTool ? nearbyTool : undefined;
},
getActiveTool: function (button) {
if (!initialized) {
toolManager.init();
} // If activeTool is not defined, we should set as defaultTool
if (!activeTool) {
activeTool = defaultTool;
} // If button is not defined, we should consider it left
if (!button) {
button = 'left';
}
return activeTool[button];
},
setDefaultTool: function (tool, button) {
// If button is not defined, we should consider it left
if (!button) {
button = 'left';
}
defaultTool[button] = tool;
},
getDefaultTool: function (button) {
// If button is not defined, we should consider it left
if (!button) {
button = 'left';
}
return defaultTool[button];
},
setConfigureTools: function (configureTools) {
if (typeof configureTools === 'function') {
this.configureTools = configureTools;
}
},
activateCommandButton: function (button) {
var activeCommandButtons = Session.get('ToolManagerActiveCommandButtons') || [];
if (activeCommandButtons.indexOf(button) === -1) {
activeCommandButtons.push(button);
Session.set('ToolManagerActiveCommandButtons', activeCommandButtons);
}
},
deactivateCommandButton: function (button) {
var activeCommandButtons = Session.get('ToolManagerActiveCommandButtons') || [];
var index = activeCommandButtons.indexOf(button);
if (index !== -1) {
activeCommandButtons.splice(index, 1);
Session.set('ToolManagerActiveCommandButtons', activeCommandButtons);
}
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"unloadHandlers.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/unloadHandlers.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
unloadHandlers: function () {
return unloadHandlers;
}
});
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
var unloadHandlers = {
beforeUnload: function (event) {
// Check for any unsaved changes on viewer namespace...
if (OHIF.ui.unsavedChanges.probe('viewer.*') > 0) {
var confirmationMessage = 'You have unsaved changes!';
event.returnValue = confirmationMessage;
return confirmationMessage;
}
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"updateAllViewports.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/updateAllViewports.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
updateAllViewports: function () {
return updateAllViewports;
}
});
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 0);
function updateAllViewports() {
var viewports = $('.imageViewerViewport').not('.empty');
viewports.each(function (index, element) {
cornerstone.updateImage(element);
});
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"updateCrosshairsSynchronizer.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/updateCrosshairsSynchronizer.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
updateCrosshairsSynchronizer: function () {
return updateCrosshairsSynchronizer;
}
});
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 0);
var getFrameOfReferenceUID;
module.watch(require("./getFrameOfReferenceUID"), {
getFrameOfReferenceUID: function (v) {
getFrameOfReferenceUID = v;
}
}, 1);
var crosshairsSynchronizers;
module.watch(require("./crosshairsSynchronizers"), {
crosshairsSynchronizers: function (v) {
crosshairsSynchronizers = v;
}
}, 2);
function updateCrosshairsSynchronizer(currentFrameOfReferenceUID) {
// Check if an old synchronizer exists, and if it does, destroy it
// If not, create a new one
var synchronizer = crosshairsSynchronizers.synchronizers[currentFrameOfReferenceUID];
if (synchronizer) {
// If it already exists, remove all source & target elements
synchronizer.destroy();
} else {
// Create a new synchronizer
crosshairsSynchronizers.synchronizers[currentFrameOfReferenceUID] = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.updateImageSynchronizer);
synchronizer = crosshairsSynchronizers.synchronizers[currentFrameOfReferenceUID];
} // Add all elements that stem from the same frame of reference
$('.imageViewerViewport').each(function (index, element) {
var frameOfReferenceUID = getFrameOfReferenceUID(element);
if (currentFrameOfReferenceUID !== frameOfReferenceUID) {
return;
}
synchronizer.add(element);
});
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"updateMetaDataManager.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/updateMetaDataManager.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
updateMetaDataManager: function () {
return updateMetaDataManager;
}
});
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 0);
var getWADORSImageId;
module.watch(require("./getWADORSImageId"), {
getWADORSImageId: function (v) {
getWADORSImageId = v;
}
}, 1);
var WadoRsMetaDataBuilder;
module.watch(require("./classes/metadata/WadoRsMetaDataBuilder"), {
WadoRsMetaDataBuilder: function (v) {
WadoRsMetaDataBuilder = v;
}
}, 2);
function getRadiopharmaceuticalInfoMetaData(instance) {
var radiopharmaceuticalInfo = instance.radiopharmaceuticalInfo;
if (instance.modality !== 'PT' || !radiopharmaceuticalInfo) {
return;
}
return new WadoRsMetaDataBuilder().addTag('00181072', radiopharmaceuticalInfo.radiopharmaceuticalStartTime).addTag('00181074', radiopharmaceuticalInfo.radionuclideTotalDose).addTag('00181075', radiopharmaceuticalInfo.radionuclideHalfLife).toJSON();
}
var getWadoRsInstanceMetaData = function (study, series, instance) {
return new WadoRsMetaDataBuilder().addTag('00080016', instance.sopClassUid).addTag('00080018', instance.sopInstanceUid).addTag('00080021', series.seriesDate).addTag('00080031', series.seriesTime).addTag('00080060', instance.modality).addTag('00101010', study.patientAge).addTag('00101020', study.patientSize).addTag('00101030', study.patientWeight).addTag('00180050', instance.sliceThickness).addTag('0020000e', series.seriesInstanceUid).addTag('00200011', series.seriesNumber).addTag('0020000d', study.studyInstanceUid).addTag('00200013', instance.instanceNumber).addTag('00200032', instance.imagePositionPatient, true).addTag('00200037', instance.imageOrientationPatient, true).addTag('00200052', instance.frameOfReferenceUID).addTag('00201041', instance.sliceLocation).addTag('00280002', instance.samplesPerPixel).addTag('00280004', instance.photometricInterpretation).addTag('00280006', instance.planarConfiguration).addTag('00280010', instance.rows).addTag('00280011', instance.columns).addTag('00280030', instance.pixelSpacing, true).addTag('00280034', instance.pixelAspectRatio, true).addTag('00280100', instance.bitsAllocated).addTag('00280101', instance.bitsStored).addTag('00280102', instance.highBit).addTag('00280103', instance.pixelRepresentation).addTag('00280106', instance.smallestPixelValue).addTag('00280107', instance.largestPixelValue).addTag('00281050', instance.windowCenter, true).addTag('00281051', instance.windowWidth, true).addTag('00281052', instance.rescaleIntercept).addTag('00281053', instance.rescaleSlope).addTag('00281054', instance.rescaleType).addTag('00281101', instance.redPaletteColorLookupTableDescriptor).addTag('00281102', instance.greenPaletteColorLookupTableDescriptor).addTag('00281103', instance.bluePaletteColorLookupTableDescriptor).addTag('00281201', instance.redPaletteColorLookupTableData).addTag('00281202', instance.greenPaletteColorLookupTableData).addTag('00281203', instance.bluePaletteColorLookupTableData).addTag('00540016', getRadiopharmaceuticalInfoMetaData(instance)).toJSON();
};
function updateMetaDataManager(study) {
study.seriesList.forEach(function (series) {
series.instances.forEach(function (instance) {
// Cache just images that are going to be loaded via WADO-RS
if (instance.imageRendering !== 'wadors' && instance.thumbnailRendering !== 'wadors') {
return;
}
var metaData = getWadoRsInstanceMetaData(study, series, instance);
var numberOfFrames = instance.numberOfFrames || 1; // We can share the same metaData with all frames because it doesn't have
// any frame specific data, such as frameNumber, pixelData, offset, etc.
// WADO-RS frame number is 1-based
for (var frameNumber = 0; frameNumber < numberOfFrames; frameNumber++) {
var imageId = getWADORSImageId(instance, frameNumber);
cornerstoneWADOImageLoader.wadors.metaDataManager.add(imageId, metaData);
}
});
});
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"updateOrientationMarkers.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/updateOrientationMarkers.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
updateOrientationMarkers: function () {
return updateOrientationMarkers;
}
});
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 0);
function updateOrientationMarkers(element, viewport) {
// Get the current viewport settings
if (!viewport) {
viewport = cornerstone.getViewport(element);
} // Updates the orientation labels on the viewport
var enabledElement = cornerstone.getEnabledElement(element);
var imagePlane = cornerstone.metaData.get('imagePlane', enabledElement.image.imageId);
if (!imagePlane || !imagePlane.rowCosines || !imagePlane.columnCosines) {
return;
}
var rowString = cornerstoneTools.orientation.getOrientationString(imagePlane.rowCosines);
var columnString = cornerstoneTools.orientation.getOrientationString(imagePlane.columnCosines);
var oppositeRowString = cornerstoneTools.orientation.invertOrientationString(rowString);
var oppositeColumnString = cornerstoneTools.orientation.invertOrientationString(columnString);
var markers = {
top: oppositeColumnString,
left: oppositeRowString
}; // If any vertical or horizontal flips are applied, change the orientation strings ahead of
// the rotation applications
if (viewport.vflip) {
markers.top = cornerstoneTools.orientation.invertOrientationString(markers.top);
}
if (viewport.hflip) {
markers.left = cornerstoneTools.orientation.invertOrientationString(markers.left);
} // Get the viewport orientation marker DOM elements
var viewportOrientationMarkers = $(element).siblings('.viewportOrientationMarkers');
var topMarker = viewportOrientationMarkers.find('.topMid');
var leftMarker = viewportOrientationMarkers.find('.leftMid'); // Swap the labels accordingly if the viewport has been rotated
// This could be done in a more complex way for intermediate rotation values (e.g. 45 degrees)
if (viewport.rotation === 90 || viewport.rotation === -270) {
topMarker.text(markers.left);
leftMarker.text(cornerstoneTools.orientation.invertOrientationString(markers.top));
} else if (viewport.rotation === -90 || viewport.rotation === 270) {
topMarker.text(cornerstoneTools.orientation.invertOrientationString(markers.left));
leftMarker.text(markers.top);
} else if (viewport.rotation === 180 || viewport.rotation === -180) {
topMarker.text(cornerstoneTools.orientation.invertOrientationString(markers.top));
leftMarker.text(cornerstoneTools.orientation.invertOrientationString(markers.left));
} else {
topMarker.text(markers.top);
leftMarker.text(markers.left);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"viewportOverlayUtils.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/viewportOverlayUtils.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
viewportOverlayUtils: function () {
return viewportOverlayUtils;
}
});
var cornerstone;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
}
}, 0);
var getElementIfNotEmpty;
module.watch(require("./getElementIfNotEmpty"), {
getElementIfNotEmpty: function (v) {
getElementIfNotEmpty = v;
}
}, 1);
var getPatient = function (property) {
if (!this.imageId) {
return false;
}
var patient = cornerstone.metaData.get('patient', this.imageId);
if (!patient) {
return '';
}
return patient[property];
};
var getStudy = function (property) {
if (!this.imageId) {
return false;
}
var study = cornerstone.metaData.get('study', this.imageId);
if (!study) {
return '';
}
return study[property];
};
var getSeries = function (property) {
if (!this.imageId) {
return false;
}
var series = cornerstone.metaData.get('series', this.imageId);
if (!series) {
return '';
}
return series[property];
};
var getInstance = function (property) {
if (!this.imageId) {
return false;
}
var instance = cornerstone.metaData.get('instance', this.imageId);
if (!instance) {
return '';
}
return instance[property];
};
var getTagDisplay = function (property) {
if (!this.imageId) {
return false;
}
var instance = cornerstone.metaData.get('tagDisplay', this.imageId);
if (!instance) {
return '';
}
return instance[property];
};
var getImage = function (viewportIndex) {
var element = getElementIfNotEmpty(viewportIndex);
if (!element) {
return false;
}
var enabledElement;
try {
enabledElement = cornerstone.getEnabledElement(element);
} catch (error) {
return false;
}
if (!enabledElement || !enabledElement.image) {
return false;
}
return enabledElement.image;
};
var formatDateTime = function (date, time) {
return date + " " + time;
};
var viewportOverlayUtils = {
getPatient: getPatient,
getStudy: getStudy,
getSeries: getSeries,
getInstance: getInstance,
getTagDisplay: getTagDisplay,
getImage: getImage,
formatDateTime: formatDateTime
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"viewportUtils.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/viewportUtils.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
viewportUtils: function () {
return viewportUtils;
}
});
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 0);
var Random;
module.watch(require("meteor/random"), {
Random: function (v) {
Random = v;
}
}, 1);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 2);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 3);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 4);
var cornerstone, cornerstoneTools;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
},
cornerstoneTools: function (v) {
cornerstoneTools = v;
}
}, 5);
var updateOrientationMarkers;
module.watch(require("./updateOrientationMarkers"), {
updateOrientationMarkers: function (v) {
updateOrientationMarkers = v;
}
}, 6);
var getInstanceClassDefaultViewport;
module.watch(require("./instanceClassSpecificViewport"), {
getInstanceClassDefaultViewport: function (v) {
getInstanceClassDefaultViewport = v;
}
}, 7);
/**
* Get a cornerstone enabledElement for a DOM Element
* @param {DOMElement} element Element to get the enabledElement from Cornerstone
* @return {Object} Cornerstone's enabledElement object for the given
* element or undefined if the element is not enabled
*/
var getEnabledElement = function (element) {
var enabledElement;
try {
enabledElement = cornerstone.getEnabledElement(element);
} catch (error) {
OHIF.log.warn(error);
}
return enabledElement;
};
/**
* Get the active viewport element. It uses activeViewport Session Variable
* @return {DOMElement} DOMElement of the current active viewport
*/
var getActiveViewportElement = function () {
var viewportIndex = Session.get('activeViewport') || 0;
return $('.imageViewerViewport').get(viewportIndex);
};
/**
* Get a cornerstone enabledElement for the Active Viewport Element
* @return {Object} Cornerstone's enabledElement object for the active
* viewport element or undefined if the element
* is not enabled
*/
var getEnabledElementForActiveElement = function () {
var activeViewportElement = getActiveViewportElement();
var enabledElement = getEnabledElement(activeViewportElement);
return enabledElement;
};
var zoomIn = function () {
var element = getActiveViewportElement();
if (!element) {
return;
}
var viewport = cornerstone.getViewport(element);
var scaleIncrement = 0.15;
var maximumScale = 10;
viewport.scale = Math.min(viewport.scale + scaleIncrement, maximumScale);
cornerstone.setViewport(element, viewport);
};
var zoomOut = function () {
var element = getActiveViewportElement();
if (!element) {
return;
}
var viewport = cornerstone.getViewport(element);
var scaleIncrement = 0.15;
var minimumScale = 0.05;
viewport.scale = Math.max(viewport.scale - scaleIncrement, minimumScale);
cornerstone.setViewport(element, viewport);
};
var zoomToFit = function () {
var element = getActiveViewportElement();
if (!element) {
return;
}
cornerstone.fitToWindow(element);
};
var rotateL = function () {
var element = getActiveViewportElement();
if (!element) {
return;
}
var viewport = cornerstone.getViewport(element);
viewport.rotation -= 90;
cornerstone.setViewport(element, viewport);
updateOrientationMarkers(element, viewport);
};
var rotateR = function () {
var element = getActiveViewportElement();
if (!element) {
return;
}
var viewport = cornerstone.getViewport(element);
viewport.rotation += 90;
cornerstone.setViewport(element, viewport);
updateOrientationMarkers(element, viewport);
};
var invert = function () {
var element = getActiveViewportElement();
if (!element) {
return;
}
var viewport = cornerstone.getViewport(element);
viewport.invert = viewport.invert === false;
cornerstone.setViewport(element, viewport);
};
var flipV = function () {
var element = getActiveViewportElement();
var viewport = cornerstone.getViewport(element);
viewport.vflip = viewport.vflip === false;
cornerstone.setViewport(element, viewport);
updateOrientationMarkers(element, viewport);
};
var flipH = function () {
var element = getActiveViewportElement();
var viewport = cornerstone.getViewport(element);
viewport.hflip = viewport.hflip === false;
cornerstone.setViewport(element, viewport);
updateOrientationMarkers(element, viewport);
};
var resetViewportWithElement = function (element) {
var enabledElement = cornerstone.getEnabledElement(element);
if (enabledElement.fitToWindow === false) {
var imageId = enabledElement.image.imageId;
var instance = cornerstone.metaData.get('instance', imageId);
enabledElement.viewport = cornerstone.getDefaultViewport(enabledElement.canvas, enabledElement.image);
var instanceClassDefaultViewport = getInstanceClassDefaultViewport(instance, enabledElement, imageId);
cornerstone.setViewport(element, instanceClassDefaultViewport);
} else {
cornerstone.reset(element);
}
};
var resetViewport = function () {
var viewportIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
if (viewportIndex === null) {
resetViewportWithElement(getActiveViewportElement());
} else if (viewportIndex === 'all') {
$('.imageViewerViewport').each(function (index, element) {
resetViewportWithElement(element);
});
} else {
resetViewportWithElement($('.imageViewerViewport').get(viewportIndex));
}
};
var clearTools = function () {
var element = getActiveViewportElement();
var toolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager;
toolStateManager.clear(element);
cornerstone.updateImage(element);
};
var linkStackScroll = function () {
var synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer;
if (!synchronizer) {
return;
}
if (synchronizer.isActive()) {
synchronizer.deactivate();
} else {
synchronizer.activate();
}
}; // This function was originally defined alone inside client/lib/toggleDialog.js
// and has been moved here to avoid circular dependency issues.
var toggleDialog = function (element, closeAction) {
var $element = $(element);
if ($element.is('dialog')) {
if (element.hasAttribute('open')) {
if (closeAction) {
closeAction();
}
element.close();
} else {
element.show();
}
} else {
var isClosed = $element.hasClass('dialog-open');
$element.toggleClass('dialog-closed', isClosed);
$element.toggleClass('dialog-open', !isClosed);
}
}; // Toggle the play/stop state for the cornerstone clip tool
var toggleCinePlay = function () {
// Get the active viewport element
var element = getActiveViewportElement(); // Check if it's playing the clip to toggle it
if (isPlaying()) {
cornerstoneTools.stopClip(element);
} else {
cornerstoneTools.playClip(element);
} // Update the UpdateCINE session property
Session.set('UpdateCINE', Math.random());
}; // Show/hide the CINE dialog
var toggleCineDialog = function () {
var dialog = document.getElementById('cineDialog');
toggleDialog(dialog, stopAllClips);
Session.set('UpdateCINE', Random.id());
};
var toggleDownloadDialog = function () {
stopActiveClip();
var $dialog = $('#imageDownloadDialog');
if ($dialog.length) {
$dialog.find('.close:first').click();
} else {
OHIF.ui.showDialog('imageDownloadDialog');
}
};
var isDownloadEnabled = function () {
var activeViewport = getActiveViewportElement();
return activeViewport ? true : false;
}; // Check if the clip is playing on the active viewport
var isPlaying = function () {
// Create a dependency on LayoutManagerUpdated and UpdateCINE session
Session.get('UpdateCINE');
Session.get('LayoutManagerUpdated'); // Get the viewport element and its current playClip tool state
var element = getActiveViewportElement(); // Empty Elements throws cornerstore exception
if (!element || !$(element).find('canvas').length) {
return;
}
var toolState = cornerstoneTools.getToolState(element, 'playClip'); // Stop here if the tool state is not defined yet
if (!toolState) {
return false;
} // Get the clip state
var clipState = toolState.data[0];
if (clipState) {
// Return true if the clip is playing
return !_.isUndefined(clipState.intervalId);
}
return false;
}; // Check if a study has multiple frames
var hasMultipleFrames = function () {
// Its called everytime active viewport and/or layout change
Session.get('activeViewport');
Session.get('LayoutManagerUpdated');
var activeViewport = getActiveViewportElement(); // No active viewport yet: disable button
if (!activeViewport || !$(activeViewport).find('canvas').length) {
return true;
} // Get images in the stack
var stackToolData = cornerstoneTools.getToolState(activeViewport, 'stack'); // No images in the stack, so disable button
if (!stackToolData || !stackToolData.data || !stackToolData.data.length) {
return true;
} // Get number of images in the stack
var stackData = stackToolData.data[0];
var nImages = stackData.imageIds && stackData.imageIds.length ? stackData.imageIds.length : 1; // Stack has just one image, so disable button
if (nImages === 1) {
return true;
}
return false;
}; // Stop clips on all non-empty elements
var stopAllClips = function () {
var elements = $('.imageViewerViewport').not('.empty');
elements.each(function (index, element) {
if ($(element).find('canvas').length) {
cornerstoneTools.stopClip(element);
}
});
};
var stopActiveClip = function () {
var activeElement = getActiveViewportElement();
if ($(activeElement).find('canvas').length) {
cornerstoneTools.stopClip(activeElement);
}
};
var isStackScrollLinkingDisabled = function () {
var linkableViewportsCount = 0; // Its called everytime active viewport and/or layout change
Session.get('activeViewport');
Session.get('LayoutManagerUpdated');
var synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer;
if (synchronizer) {
var linkableViewports = synchronizer.getLinkableViewports();
linkableViewportsCount = linkableViewports.length;
}
return linkableViewportsCount <= 1;
};
var isStackScrollLinkingActive = function () {
var isActive = true; // Its called everytime active viewport layout changes
Session.get('LayoutManagerUpdated');
var synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer;
if (!synchronizer) {
return;
}
var syncedElements = _.pluck(synchronizer.syncedViewports, 'element');
var $renderedViewports = $('.imageViewerViewport');
$renderedViewports.each(function (index, element) {
if (!_.contains(syncedElements, element)) {
isActive = false;
}
});
return isActive;
}; // Create an event listener to update playing state when a clip stops playing
window.addEventListener('cornerstonetoolsclipstopped', function () {
Session.set('UpdateCINE', Math.random());
});
/**
* Export functions inside viewportUtils namespace.
*/
var viewportUtils = {
getEnabledElementForActiveElement: getEnabledElementForActiveElement,
getEnabledElement: getEnabledElement,
getActiveViewportElement: getActiveViewportElement,
zoomIn: zoomIn,
zoomOut: zoomOut,
zoomToFit: zoomToFit,
rotateL: rotateL,
rotateR: rotateR,
invert: invert,
flipV: flipV,
flipH: flipH,
resetViewport: resetViewport,
clearTools: clearTools,
linkStackScroll: linkStackScroll,
toggleDialog: toggleDialog,
toggleCinePlay: toggleCinePlay,
toggleCineDialog: toggleCineDialog,
toggleDownloadDialog: toggleDownloadDialog,
isPlaying: isPlaying,
isDownloadEnabled: isDownloadEnabled,
hasMultipleFrames: hasMultipleFrames,
stopAllClips: stopAllClips,
isStackScrollLinkingDisabled: isStackScrollLinkingDisabled,
isStackScrollLinkingActive: isStackScrollLinkingActive
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"classes":{"ImageSet.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/ImageSet.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
module.export({
ImageSet: function () {
return ImageSet;
}
});
var Random;
module.watch(require("meteor/random"), {
Random: function (v) {
Random = v;
}
}, 0);
var OHIFError;
module.watch(require("./OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 1);
var OBJECT = 'object';
/**
* This class defines an ImageSet object which will be used across the viewer. This object represents
* a list of images that are associated by any arbitrary criteria being thus content agnostic. Besides the
* main attributes (images and uid) it allows additional attributes to be appended to it (currently
* indiscriminately, but this should be changed).
*/
var ImageSet =
/*#__PURE__*/
function () {
function ImageSet(images) {
if (Array.isArray(images) !== true) {
throw new OHIFError('ImageSet expects an array of images');
} // @property "images"
Object.defineProperty(this, 'images', {
enumerable: false,
configurable: false,
writable: false,
value: images
}); // @property "uid"
Object.defineProperty(this, 'uid', {
enumerable: false,
configurable: false,
writable: false,
value: Random.id() // Unique ID of the instance
});
}
var _proto = ImageSet.prototype;
_proto.getUID = function () {
function getUID() {
return this.uid;
}
return getUID;
}();
_proto.setAttribute = function () {
function setAttribute(attribute, value) {
this[attribute] = value;
}
return setAttribute;
}();
_proto.getAttribute = function () {
function getAttribute(attribute) {
return this[attribute];
}
return getAttribute;
}();
_proto.setAttributes = function () {
function setAttributes(attributes) {
if ((0, _typeof2.default)(attributes) === OBJECT && attributes !== null) {
var imageSet = this,
hasOwn = Object.prototype.hasOwnProperty;
for (var attribute in meteorBabelHelpers.sanitizeForInObject(attributes)) {
if (hasOwn.call(attributes, attribute)) {
imageSet[attribute] = attributes[attribute];
}
}
}
}
return setAttributes;
}();
_proto.getImage = function () {
function getImage(index) {
return this.images[index];
}
return getImage;
}();
_proto.sortBy = function () {
function sortBy(sortingCallback) {
return this.images.sort(sortingCallback);
}
return sortBy;
}();
return ImageSet;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"LayoutManager.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/LayoutManager.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
LayoutManager: function () {
return LayoutManager;
}
});
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 1);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 2);
var Tracker;
module.watch(require("meteor/tracker"), {
Tracker: function (v) {
Tracker = v;
}
}, 3);
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 4);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 5);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 6);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 7);
var PLUGIN_CORNERSTONE = 'cornerstone';
var isInteractingWithViewport = false;
Meteor.startup(function () {
var setInteracting = function (flag) {
isInteractingWithViewport = flag;
};
var $body = $('body');
$body.on('mousedown', '.imageViewerViewport', function () {
return setInteracting(true);
});
$body.on('mouseup', function () {
return setInteracting(false);
});
}); // Displays Series in Viewports given a Protocol and list of Studies
var LayoutManager =
/*#__PURE__*/
function () {
/**
* Constructor: initializes a Layout Manager object.
* @param {DOM element} parentNode DOM element representing the parent node, which wraps the Layout Manager content
* @param {Array} studies Array of studies objects that will be rendered in the Viewer. Each object will be rendered in a div.imageViewerViewport
*/
function LayoutManager(parentNode, studies) {
var _this = this;
OHIF.log.info('LayoutManager constructor');
this.observer = new Tracker.Dependency();
this.parentNode = parentNode;
this.studies = studies;
this.viewportData = [];
this.layoutTemplateName = 'gridLayout';
this.layoutProps = {
rows: 1,
columns: 1
};
this.layoutClassName = this.getLayoutClass();
this.isZoomed = false;
var updateSessionFn = function () {
var random = Math.random();
Session.set('LayoutManagerUpdated', random);
_this.observer.changed();
};
this.updateSession = _.throttle(updateSessionFn, 300, {
leading: true,
trailing: false
});
}
/**
* Returns the number of viewports rendered, based on layoutProps
* @return {integer} number of viewports
*/
var _proto = LayoutManager.prototype;
_proto.getNumberOfViewports = function () {
function getNumberOfViewports() {
return this.layoutProps.rows * this.layoutProps.columns;
}
return getNumberOfViewports;
}();
/**
* It creates a new viewport data. This is useful for the first rendering when no viewportData is set yet.
*/
_proto.setDefaultViewportData = function () {
function setDefaultViewportData() {
OHIF.log.info('LayoutManager setDefaultViewportData');
var self = this; // Get the number of viewports to be rendered
var viewportsAmount = this.getNumberOfViewports(); // Store the old viewport data and reset the current
var oldViewportData = self.viewportData; // Get the studies and display sets sequence map
var sequenceMap = this.getDisplaySetSequenceMap(); // Check if the display sets are sequenced
var isSequenced = this.isDisplaySetsSequenced(sequenceMap); // Define the current viewport index and the viewport data array
var currentViewportIndex = 0;
if (viewportsAmount > oldViewportData.length && oldViewportData.length && isSequenced) {
// Keep the displayed display sets
self.viewportData = oldViewportData;
currentViewportIndex = oldViewportData.length;
} else if (viewportsAmount <= oldViewportData.length) {
// Reduce the original displayed display sets
self.viewportData = oldViewportData.slice(0, viewportsAmount);
return;
} else {
// Reset all display sets
self.viewportData = [];
} // Get all the display sets for the viewer studies
var displaySets = [];
this.studies.forEach(function (study) {
study.displaySets.forEach(function (dSet) {
return dSet.images.length && displaySets.push(dSet);
});
}); // Get the display sets that will be appended to the current ones
var appendix;
var currentLength = self.viewportData.length;
if (currentLength) {
// TODO: isolate displaySets array by study (maybe a map?)
var beginIndex = sequenceMap.values().next().value[0].displaySetIndex + currentLength;
var endIndex = beginIndex + (viewportsAmount - currentLength);
appendix = displaySets.slice(beginIndex, endIndex);
} else {
// Get available display sets from the first to the grid size
appendix = displaySets.slice(0, viewportsAmount);
} // Generate the additional data based on the appendix
var additionalData = [];
appendix.forEach(function (displaySet, index) {
var images = displaySet.images,
studyInstanceUid = displaySet.studyInstanceUid,
seriesInstanceUid = displaySet.seriesInstanceUid,
displaySetInstanceUid = displaySet.displaySetInstanceUid;
var sopInstanceUid = images[0] && images[0].getSOPInstanceUID ? images[0].getSOPInstanceUID() : '';
var viewportIndex = currentViewportIndex + index;
var data = {
viewportIndex: viewportIndex,
studyInstanceUid: studyInstanceUid,
seriesInstanceUid: seriesInstanceUid,
displaySetInstanceUid: displaySetInstanceUid,
sopInstanceUid: sopInstanceUid,
plugin: PLUGIN_CORNERSTONE
};
additionalData.push(data);
}); // Append the additional data with the viewport data
self.viewportData = self.viewportData.concat(additionalData); // Push empty objects if the amount is lesser than the grid size
while (self.viewportData.length < viewportsAmount) {
self.viewportData.push({});
}
}
return setDefaultViewportData;
}();
/**
* Returns the name of the class to be added to the parentNode
* @return {string} class name following the pattern layout-<rows>-<columns>. Ex: layout-1-1, layout-2-2
*/
_proto.getLayoutClass = function () {
function getLayoutClass() {
var _this$layoutProps = this.layoutProps,
rows = _this$layoutProps.rows,
columns = _this$layoutProps.columns;
var layoutClass = "layout-" + rows + "-" + columns;
return layoutClass;
}
return getLayoutClass;
}();
/**
* Add a class to the parentNode based on the layout configuration.
* This function is helpful to style the layout of viewports.
* Besides that, each inner div.viewportContainer will have helpful classes
* as well. See viewer/components/gridLayout/ component in this ohif-viewerbase package.
*/
_proto.updateLayoutClass = function () {
function updateLayoutClass() {
var newLayoutClass = this.getLayoutClass(); // If layout has changed, change its class
if (this.layoutClassName !== newLayoutClass) {
this.parentNode.classList.remove(this.layoutClassName);
}
this.layoutClassName = newLayoutClass;
this.parentNode.classList.add(newLayoutClass);
}
return updateLayoutClass;
}();
/**
* Updates the grid with the new layout props.
* It iterates over all viewportData to render the studies
* in the viewports.
* If no viewportData or no viewports defined, it renders the default viewport data.
*/
_proto.updateViewports = function () {
function updateViewports() {
OHIF.log.info('LayoutManager updateViewports');
if (!this.viewportData || !this.viewportData.length || this.viewportData.length !== this.getNumberOfViewports()) {
this.setDefaultViewportData();
}
this.viewportData.forEach(function (data) {
if (!data.plugin) {
data.plugin = PLUGIN_CORNERSTONE;
}
}); // imageViewerViewports occasionally needs relevant layout data in order to set
// the element style of the viewport in question
var layoutProps = this.layoutProps;
var data = $.extend({
viewportData: []
}, layoutProps);
this.viewportData.forEach(function (viewportData) {
var viewportDataAndLayoutProps = $.extend(viewportData, layoutProps);
data.viewportData.push(viewportDataAndLayoutProps);
});
var layoutTemplate = Template[this.layoutTemplateName];
this.parentNode.innerHTML = '';
this.updateLayoutClass();
Blaze.renderWithData(layoutTemplate, data, this.parentNode);
this.updateSession();
this.isZoomed = false;
}
return updateViewports;
}();
/**
* This function destroys and re-renders the imageViewerViewport template.
* It uses the data provided to load a new display set into the produced viewport.
* @param {integer} viewportIndex index of the viewport to be re-rendered
* @param {Object} data instance data object
*/
_proto.rerenderViewportWithNewDisplaySet = function () {
function rerenderViewportWithNewDisplaySet(viewportIndex, viewportData) {
// Clone the data to prevent changing the original object
var data = _.clone(viewportData);
OHIF.log.info("LayoutManager rerenderViewportWithNewDisplaySet: " + viewportIndex); // The parent container is identified because it is later removed from the DOM
var container = $('.viewportContainer').get(viewportIndex); // Record the current viewportIndex so this can be passed into the re-rendering call
data.viewportIndex = viewportIndex; // If we have been provided with a plugin to use, use it.
// Otherwise, use whichever plugin is currently in use in this viewport.
var plugin = data.plugin || this.viewportData[viewportIndex].plugin;
var pluginData = data.pluginData || this.viewportData[viewportIndex].pluginData; // Update the dictionary of loaded displaySet for the specified viewport
this.viewportData[viewportIndex] = {
viewportIndex: viewportIndex,
displaySetInstanceUid: data.displaySetInstanceUid,
seriesInstanceUid: data.seriesInstanceUid,
studyInstanceUid: data.studyInstanceUid,
renderedCallback: data.renderedCallback,
currentImageIdIndex: data.currentImageIdIndex || 0,
plugin: plugin,
pluginData: pluginData
};
var newViewportContainer = document.createElement('div'); // Render and insert the template
if (plugin === PLUGIN_CORNERSTONE) {
// Remove the hover styling
var element = $(container).find('.imageViewerViewport');
element.find('canvas').not('.magnifyTool').removeClass('faded'); // Remove the whole template, add in the new one
var viewportContainer = element.parents('.removable');
newViewportContainer.className = 'removable'; // Remove the parent element of the template
// This is a workaround since otherwise Blaze UI onDestroyed doesn't fire
viewportContainer.remove();
container.appendChild(newViewportContainer);
Blaze.renderWithData(Template.imageViewerViewport, data, newViewportContainer);
} else {
newViewportContainer.className = "viewport-plugin-" + plugin;
newViewportContainer.style.width = '100%';
newViewportContainer.style.height = '100%';
container.innerHTML = '';
container.appendChild(newViewportContainer);
}
this.updateSession();
}
return rerenderViewportWithNewDisplaySet;
}();
/**
* Enlarge a single viewport. Useful when the layout has more than one viewport
* @param {integer} viewportIndex Index of the viewport to be enlarged
*/
_proto.enlargeViewport = function () {
function enlargeViewport(viewportIndex) {
OHIF.log.info("LayoutManager enlargeViewport: " + viewportIndex);
if (!this.viewportData || !this.viewportData.length) {
return;
} // Clone the array for later
this.previousViewportData = this.viewportData.slice(0);
var singleViewportData = $.extend({}, this.viewportData[viewportIndex]);
singleViewportData.rows = 1;
singleViewportData.columns = 1;
singleViewportData.viewportIndex = 0;
var data = {
viewportData: [singleViewportData],
rows: 1,
columns: 1
};
var layoutTemplate = Template.gridLayout;
this.parentNode.innerHTML = '';
Blaze.renderWithData(layoutTemplate, data, this.parentNode);
this.isZoomed = true;
this.zoomedViewportIndex = viewportIndex;
this.viewportData = data.viewportData;
this.updateSession();
}
return enlargeViewport;
}();
/**
* Resets to the previous layout configuration.
* Useful after enlarging a single viewport.
*/
_proto.resetPreviousLayout = function () {
function resetPreviousLayout() {
OHIF.log.info('LayoutManager resetPreviousLayout');
if (!this.isZoomed) {
return;
}
this.previousViewportData[this.zoomedViewportIndex] = $.extend({}, this.viewportData[0]);
this.previousViewportData[this.zoomedViewportIndex].viewportIndex = this.zoomedViewportIndex;
this.viewportData = this.previousViewportData;
this.updateViewports();
}
return resetPreviousLayout;
}();
/**
* Toogle viewport enlargement.
* Useful for user to enlarge or going back to previous layout configurations
* @param {integer} viewportIndex Index of the viewport to be toggled
*/
_proto.toggleEnlargement = function () {
function toggleEnlargement(viewportIndex) {
OHIF.log.info("LayoutManager toggleEnlargement: " + viewportIndex);
if (this.isZoomed) {
this.resetPreviousLayout();
} else {
// Don't enlarge the viewport if we only have one Viewport
// to begin with
if (this.getNumberOfViewports() > 1) {
this.enlargeViewport(viewportIndex);
}
}
}
return toggleEnlargement;
}();
/**
* Return the display sets map sequence of display sets and viewports
*/
_proto.getDisplaySetSequenceMap = function () {
function getDisplaySetSequenceMap() {
var _this2 = this;
OHIF.log.info('LayoutManager getDisplaySetSequenceMap'); // Get the viewport data list
var viewportDataList = this.viewportData; // Create a map to control the display set sequence
var sequenceMap = new Map(); // Iterate over each viewport and register its details on the sequence map
viewportDataList.forEach(function (viewportData, viewportIndex) {
// Get the current study
var currentStudy = _.findWhere(_this2.studies, {
studyInstanceUid: viewportData.studyInstanceUid
}) || _this2.studies[0]; // Get the display sets
var displaySets = currentStudy.displaySets; // Get the current display set
var displaySet = _.findWhere(displaySets, {
displaySetInstanceUid: viewportData.displaySetInstanceUid
}); // Get the current instance index (using 9999 to sort greater than -1)
var displaySetIndex = _.indexOf(displaySets, displaySet);
displaySetIndex = displaySetIndex < 0 ? 9999 : displaySetIndex; // Try to get a map entry for current study or create it if not present
var studyViewports = sequenceMap.get(currentStudy);
if (!studyViewports) {
studyViewports = [];
sequenceMap.set(currentStudy, studyViewports);
} // Register the viewport index and the display set index on the map
studyViewports.push({
viewportIndex: viewportIndex,
displaySetIndex: displaySetIndex
});
}); // Return the generated sequence map
return sequenceMap;
}
return getDisplaySetSequenceMap;
}();
/**
* Check if all the display sets and viewports are sequenced
* @param {Array} definedSequenceMap Array of display set sequence map
* @return {Boolean} Returns if the display set sequence map is sequenced or not
*/
_proto.isDisplaySetsSequenced = function () {
function isDisplaySetsSequenced(definedSequenceMap) {
OHIF.log.info('LayoutManager isDisplaySetsSequenced');
var isSequenced = true; // Get the studies and display sets sequence map
var sequenceMap = definedSequenceMap || this.getDisplaySetSequenceMap();
sequenceMap.forEach(function (studyViewports, study) {
var lastDisplaySetIndex = null;
var lastViewportIndex = null;
studyViewports.forEach(function (_ref, index) {
var viewportIndex = _ref.viewportIndex,
displaySetIndex = _ref.displaySetIndex;
// Check if the sequence is wrong
if (displaySetIndex !== 9999 && lastViewportIndex !== null && lastDisplaySetIndex !== null && displaySetIndex !== null && (viewportIndex - 1 !== lastViewportIndex || displaySetIndex - 1 !== lastDisplaySetIndex)) {
// Set the sequenced flag as false;
isSequenced = false;
} // Update the last viewport index
lastViewportIndex = viewportIndex; // Update the last display set index
lastDisplaySetIndex = displaySetIndex;
});
});
return isSequenced;
}
return isDisplaySetsSequenced;
}();
/**
* Check if is possible to move display sets on a specific direction.
* It checks if looping is allowed by OHIF.uiSettings.displaySetNavigationLoopOverSeries
* @param {Boolean} isNext Represents the direction
* @return {Boolean} Returns if display sets can be moved
*/
_proto.canMoveDisplaySets = function () {
function canMoveDisplaySets(isNext) {
OHIF.log.info('LayoutManager canMoveDisplaySets'); // Get the setting that defines if the display set navigation is multiple
var isMultiple = OHIF.uiSettings.displaySetNavigationMultipleViewports; // Get the setting that allow display set navigation looping over series
var allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries; // Get the studies and display sets sequence map
var sequenceMap = this.getDisplaySetSequenceMap(); // Check if the display sets are sequenced
var isSequenced = this.isDisplaySetsSequenced(sequenceMap); // Get Active Viewport Index if isMultiple is false
var activeViewportIndex = !isMultiple ? Session.get('activeViewport') : null; // Check if is next and looping is blocked
if (isNext && !allowLooping) {
// Check if the end was reached
var endReached = true;
sequenceMap.forEach(function (studyViewports, study) {
// Get active viewport index if isMultiple is false ortherwise get last
var studyViewport = studyViewports[activeViewportIndex !== null ? activeViewportIndex : studyViewports.length - 1];
if (!studyViewport) {
return;
}
var viewportIndex = studyViewport.displaySetIndex;
var layoutViewports = studyViewports.length;
var amount = study.displaySets.length;
var move = !isMultiple ? 1 : amount % layoutViewports || layoutViewports;
var lastStepIndex = amount - move; // 9999 for index means empty viewport, see getDisplaySetSequenceMap function
if (viewportIndex !== 9999 && viewportIndex !== lastStepIndex) {
endReached = false;
}
}); // Return false if end is not reached yet
if ((!isMultiple || isSequenced) && endReached) {
return false;
}
} // Check if is previous and looping is blocked
if (!isNext && !allowLooping) {
// Check if the begin was reached
var beginReached = true;
if (activeViewportIndex >= 0) {
sequenceMap.forEach(function (studyViewports, study) {
// Get active viewport index if isMultiple is false ortherwise get first
var studyViewport = studyViewports[activeViewportIndex !== null ? activeViewportIndex : 0];
if (!studyViewport) {
return;
}
var viewportIndex = studyViewport.displaySetIndex;
var layoutViewports = studyViewports.length; // 9999 for index means empty viewport, see getDisplaySetSequenceMap function
if (viewportIndex !== 9999 && viewportIndex - layoutViewports !== -layoutViewports) {
beginReached = false;
}
});
} // Return false if begin is not reached yet
if ((!isMultiple || isSequenced) && beginReached) {
return false;
}
}
return true;
}
return canMoveDisplaySets;
}();
/**
* Move display sets forward or backward in the given viewport index
* @param {integer} viewportIndex Index of the viewport to be moved
* @param {Boolean} isNext Represents the direction (true = forward, false = backward)
*/
_proto.moveSingleViewportDisplaySets = function () {
function moveSingleViewportDisplaySets(viewportIndex, isNext) {
OHIF.log.info("LayoutManager moveSingleViewportDisplaySets: " + viewportIndex); // Get the setting that allow display set navigation looping over series
var allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries; // Get the selected viewport data
var viewportData = this.viewportData[viewportIndex]; // Get the current study
var currentStudy = _.findWhere(this.studies, {
studyInstanceUid: viewportData.studyInstanceUid
}) || this.studies[0]; // Get the display sets
var displaySets = currentStudy.displaySets; // Get the current display set
var currentDisplaySet = _.findWhere(displaySets, {
displaySetInstanceUid: viewportData.displaySetInstanceUid
}); // Get the new index and ensure that it will exists in display sets
var newIndex = _.indexOf(displaySets, currentDisplaySet);
if (isNext) {
newIndex++;
if (newIndex >= displaySets.length) {
// Stop here if looping is not allowed
if (!allowLooping) {
return;
}
newIndex = 0;
}
} else {
newIndex--;
if (newIndex < 0) {
// Stop here if looping is not allowed
if (!allowLooping) {
return;
}
newIndex = displaySets.length - 1;
}
} // Get the display set data for the new index
var newDisplaySetData = displaySets[newIndex]; // Rerender the viewport using the new display set data
this.rerenderViewportWithNewDisplaySet(viewportIndex, newDisplaySetData);
}
return moveSingleViewportDisplaySets;
}();
/**
* Move multiple display sets forward or backward in all viewports
* @param {Boolean} isNext Represents the direction (true = forward, false = backward)
*/
_proto.moveMultipleViewportDisplaySets = function () {
function moveMultipleViewportDisplaySets(isNext) {
var _this3 = this;
OHIF.log.info('LayoutManager moveMultipleViewportDisplaySets'); // Get the setting that allow display set navigation looping over series
var allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries; // Create a map to control the display set sequence
var sequenceMap = this.getDisplaySetSequenceMap(); // Check if the display sets are sequenced
var isSequenced = this.isDisplaySetsSequenced(sequenceMap);
var displaySetsToRender = []; // Iterate over the studies map and move its display sets
sequenceMap.forEach(function (studyViewports, study) {
// Sort the viewports on the study by the display set index
studyViewports.sort(function (a, b) {
return a.displaySetIndex > b.displaySetIndex;
}); // Get the study display sets
var displaySets = study.displaySets; // Calculate the base index
var firstIndex = studyViewports[0].displaySetIndex;
var steps = studyViewports.length;
var rest = firstIndex % steps;
var baseIndex = rest ? firstIndex - rest : firstIndex;
var direction = isNext ? 1 : -1;
baseIndex += steps * direction;
var amount = displaySets.length; // Check if the indexes are sequenced or will overflow the array bounds
if (baseIndex >= amount) {
var move = amount % steps || steps;
var lastStepIndex = amount - move;
if (firstIndex + steps !== lastStepIndex + steps) {
// Reset the index if the display sets are sequenced but shifted
baseIndex = lastStepIndex;
} else if (!allowLooping) {
// Stop here if looping is not allowed
return;
} else {
// Start over the series if looping is allowed
baseIndex = 0;
}
} else if (baseIndex < 0) {
if (firstIndex > 0) {
// Reset the index if the display sets are sequenced but shifted
baseIndex = 0;
} else if (!allowLooping) {
// Stop here if looping is not allowed
return;
} else {
// Go to the series' end if looping is allowed
baseIndex = amount - 1 - (amount - 1) % steps;
}
} else if (!isSequenced) {
// Reset the sequence if indexes are not sequenced
baseIndex = 0;
} // Iterate over the current study viewports
studyViewports.forEach(function (_ref2, index) {
var viewportIndex = _ref2.viewportIndex;
// Get the new displaySet index to be rendered in viewport
var newIndex = baseIndex + index; // Get the display set data for the new index
var displaySetData = displaySets[newIndex] || {}; // Add the current display set that on the render list
displaySetsToRender.push(displaySetData);
});
}); // Sort the display sets
var sortingFunction = OHIF.utils.sortBy({
name: 'studyInstanceUid'
}, {
name: 'instanceNumber'
}, {
name: 'seriesNumber'
});
displaySetsToRender.sort(function (a, b) {
return sortingFunction(a, b);
}); // Iterate over each display set data and render on its respective viewport
displaySetsToRender.forEach(function (data, index) {
_this3.rerenderViewportWithNewDisplaySet(index, data);
});
}
return moveMultipleViewportDisplaySets;
}();
/**
* Move display sets forward or backward
* @param {Boolean} isNext Represents the direction (true = forward, false = backward)
*/
_proto.moveDisplaySets = function () {
function moveDisplaySets(isNext) {
// Prevent display sets navigation while interacting with any cornerstone tool
if (isInteractingWithViewport) return;
OHIF.log.info('LayoutManager moveDisplaySets'); //Check if navigation is on a single or multiple viewports
if (OHIF.uiSettings.displaySetNavigationMultipleViewports) {
// Move display sets on multiple viewports
this.moveMultipleViewportDisplaySets(isNext);
} else {
// Get the selected viewport index
var viewportIndex = Session.get('activeViewport'); // Move display sets on a single viewport
this.moveSingleViewportDisplaySets(viewportIndex, isNext);
}
}
return moveDisplaySets;
}();
/**
* Check if a study is loaded into a viewport
* @param {string} studyInstanceUid Study instance Uid string
* @param {integer} viewportIndex Index of the viewport to be checked
* @return {Boolean} Returns if the given study is in the given viewport or not
*/
_proto.isStudyLoadedIntoViewport = function () {
function isStudyLoadedIntoViewport(studyInstanceUid, viewportIndex) {
return this.viewportData.find(function (item) {
return item.studyInstanceUid === studyInstanceUid && item.viewportIndex === viewportIndex;
}) !== void 0;
}
return isStudyLoadedIntoViewport;
}();
/**
* Check if the layout has multiple rows and columns
* @return {Boolean} Return if the layout has multiple rows and columns or not
*/
_proto.isMultipleLayout = function () {
function isMultipleLayout() {
return this.layoutProps.row !== 1 && this.layoutProps.columns !== 1;
}
return isMultipleLayout;
}();
return LayoutManager;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"OHIFError.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/OHIFError.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapNativeSuper"));
module.export({
OHIFError: function () {
return OHIFError;
}
});
var OHIFError =
/*#__PURE__*/
function (_Error) {
(0, _inheritsLoose2.default)(OHIFError, _Error);
function OHIFError(message) {
var _this;
_this = _Error.call(this) || this;
_this.message = message;
_this.stack = new Error().stack;
_this.name = _this.constructor.name;
return _this;
}
return OHIFError;
}((0, _wrapNativeSuper2.default)(Error));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"ResizeViewportManager.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/ResizeViewportManager.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
ResizeViewportManager: function () {
return ResizeViewportManager;
}
});
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 0);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 1);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 2);
var getInstanceClassDefaultViewport;
module.watch(require("../instanceClassSpecificViewport"), {
getInstanceClassDefaultViewport: function (v) {
getInstanceClassDefaultViewport = v;
}
}, 3);
var ResizeViewportManager =
/*#__PURE__*/
function () {
function ResizeViewportManager() {
this._resizeHandler = null;
} // Reposition Study Series Quick Switch based whether side bars are opened or not
var _proto = ResizeViewportManager.prototype;
_proto.repositionStudySeriesQuickSwitch = function () {
function repositionStudySeriesQuickSwitch() {
OHIF.log.info('ResizeViewportManager repositionStudySeriesQuickSwitch'); // Stop here if viewer is not displayed
var isViewer = Session.get('ViewerOpened');
if (!isViewer) return; // Stop here if there is no one or only one viewport
var nViewports = OHIF.viewerbase.layoutManager.viewportData.length;
if (!nViewports || nViewports <= 1) return;
var $viewer = $('#viewer');
var leftSidebar = $viewer.find('.sidebar-left.sidebar-open');
var rightSidebar = $viewer.find('.sidebar-right.sidebar-open');
var $leftQuickSwitch = $('.quickSwitchWrapper.left');
var $rightQuickSwitch = $('.quickSwitchWrapper.right');
var hasLeftSidebar = leftSidebar.length > 0;
var hasRightSidebar = rightSidebar.length > 0;
$rightQuickSwitch.removeClass('left-sidebar-only');
$leftQuickSwitch.removeClass('right-sidebar-only');
var leftOffset = 0;
if (hasLeftSidebar) {
leftOffset = leftSidebar.width() / $(window).width() * 100;
if (!hasRightSidebar) {
$rightQuickSwitch.addClass('left-sidebar-only');
}
}
if (hasRightSidebar && !hasLeftSidebar) {
$leftQuickSwitch.addClass('right-sidebar-only');
}
var leftPosition = $('#imageViewerViewports').width() / nViewports / $(window).width() * 100 + leftOffset;
var rightPosition = 100 - leftPosition;
$leftQuickSwitch.css('right', rightPosition + '%');
$rightQuickSwitch.css('left', leftPosition + '%');
}
return repositionStudySeriesQuickSwitch;
}(); // Relocate dialogs positions
_proto.relocateDialogs = function () {
function relocateDialogs() {
OHIF.log.info('ResizeViewportManager relocateDialogs');
var $bottomRightDialogs = $('#annotationDialog, #textMarkerOptionsDialog');
$bottomRightDialogs.css({
top: '',
// This removes the CSS property completely
left: '',
bottom: 0,
right: 0
});
var centerDialogs = $('.draggableDialog').not($bottomRightDialogs);
centerDialogs.css({
top: 0,
left: 0,
bottom: 0,
right: 0
});
}
return relocateDialogs;
}(); // Resize viewport scrollbars
_proto.resizeScrollbars = function () {
function resizeScrollbars(element) {
OHIF.log.info('ResizeViewportManager resizeScrollbars');
var $currentOverlay = $(element).siblings('.imageViewerViewportOverlay');
$currentOverlay.find('.scrollbar').trigger('rescale');
}
return resizeScrollbars;
}(); // Resize a single viewport element
_proto.resizeViewportElement = function () {
function resizeViewportElement(element) {
var fitToWindow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var enabledElement;
try {
enabledElement = cornerstone.getEnabledElement(element);
} catch (error) {
return;
}
cornerstone.resize(element, fitToWindow);
if (enabledElement.fitToWindow === false) {
var imageId = enabledElement.image.imageId;
var instance = cornerstone.metaData.get('instance', imageId);
var instanceClassViewport = getInstanceClassDefaultViewport(instance, enabledElement, imageId);
cornerstone.setViewport(element, instanceClassViewport);
}
}
return resizeViewportElement;
}(); // Resize each viewport element
_proto.resizeViewportElements = function () {
function resizeViewportElements() {
var _this = this;
this.relocateDialogs();
setTimeout(function () {
_this.repositionStudySeriesQuickSwitch();
var elements = $('.imageViewerViewport').not('.empty');
elements.each(function (index, element) {
_this.resizeViewportElement(element);
_this.resizeScrollbars(element);
});
}, 1);
}
return resizeViewportElements;
}(); // Function to override resizeViewportElements function
_proto.setResizeViewportElement = function () {
function setResizeViewportElement(resizeViewportElements) {
this.resizeViewportElements = resizeViewportElements;
}
return setResizeViewportElement;
}(); // Avoid doing DOM manipulation during the resize handler
// because it is fired very often.
// Resizing is therefore performed 100 ms after the resize event stops.
_proto.handleResize = function () {
function handleResize() {
var _this2 = this;
clearTimeout(this.resizeTimer);
this.resizeTimer = setTimeout(function () {
OHIF.log.info('ResizeViewportManager resizeViewportElements');
_this2.resizeViewportElements();
}, 100);
}
return handleResize;
}();
/**
* Returns a unique event handler function associated with a given instance using lazy assignment.
* @return {function} Returns a unique copy of the event handler of this class.
*/
_proto.getResizeHandler = function () {
function getResizeHandler() {
var resizeHandler = this._resizeHandler;
if (resizeHandler === null) {
resizeHandler = this.handleResize.bind(this);
this._resizeHandler = resizeHandler;
}
return resizeHandler;
}
return getResizeHandler;
}();
return ResizeViewportManager;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"StackImagePositionOffsetSynchronizer.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/StackImagePositionOffsetSynchronizer.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
module.export({
StackImagePositionOffsetSynchronizer: function () {
return StackImagePositionOffsetSynchronizer;
}
});
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 0);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 1);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 2);
var cornerstone, cornerstoneTools;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
},
cornerstoneTools: function (v) {
cornerstoneTools = v;
}
}, 3);
var toolManager;
module.watch(require("../toolManager"), {
toolManager: function (v) {
toolManager = v;
}
}, 4);
var StackImagePositionOffsetSynchronizer =
/*#__PURE__*/
function () {
function StackImagePositionOffsetSynchronizer() {
this.active = false;
this.syncedViewports = [];
this.synchronizer = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.stackImagePositionOffsetSynchronizer);
}
var _proto = StackImagePositionOffsetSynchronizer.prototype;
_proto.isActive = function () {
function isActive() {
return this.active;
}
return isActive;
}();
_proto.activate = function () {
function activate() {
var viewports = this.getLinkableViewports();
this.syncViewports(viewports);
}
return activate;
}();
_proto.activateByViewportIndexes = function () {
function activateByViewportIndexes(viewportIndexes) {
var viewports = this.getViewportByIndexes(viewportIndexes);
this.syncViewports(viewports);
}
return activateByViewportIndexes;
}();
_proto.deactivate = function () {
function deactivate() {
if (!this.isActive()) {
return;
}
while (this.syncedViewports.length) {
var viewport = this.syncedViewports[0];
this.removeViewport(viewport);
}
this.active = false;
toolManager.deactivateCommandButton('linkStackScroll');
}
return deactivate;
}();
_proto.update = function () {
function update() {
if (!this.isActive()) {
return;
}
var activeViewportElement = this.getActiveViewportElement();
if (this.isViewportSynced(activeViewportElement)) {
return;
}
this.deactivate();
this.activate();
}
return update;
}();
_proto.syncViewports = function () {
function syncViewports(viewports) {
var _this = this;
var viewportIndexes = [];
if (this.isActive() || viewports.length <= 1) {
return;
}
viewports.forEach(function (viewport, index) {
_this.synchronizer.add(viewport.element);
_this.syncedViewports.push(viewport);
viewportIndexes.push(viewport.index);
if (!_this.disabledListener) {
_this.disabledListener = _this.elementDisabledHandler(_this);
}
viewport.element.addEventListener(StackImagePositionOffsetSynchronizer.ELEMENT_DISABLED_EVENT, _this.disabledListener);
});
this.active = true;
toolManager.activateCommandButton('linkStackScroll');
Session.set('StackImagePositionOffsetSynchronizerLinkedViewports', viewportIndexes);
}
return syncViewports;
}();
_proto.isViewportSynced = function () {
function isViewportSynced(viewportElement) {
return !!this.getViewportByElement(viewportElement);
}
return isViewportSynced;
}();
_proto.getActiveViewportElement = function () {
function getActiveViewportElement() {
var viewportIndex = Session.get('activeViewport') || 0;
return $('.imageViewerViewport').get(viewportIndex);
}
return getActiveViewportElement;
}();
_proto.removeViewport = function () {
function removeViewport(viewport) {
var index = this.syncedViewports.indexOf(viewport);
if (index === -1) {
return;
}
this.syncedViewports.splice(index, 1);
this.synchronizer.remove(viewport.element);
this.removeLinkedViewportFromSession(viewport);
viewport.element.removeEventListener(StackImagePositionOffsetSynchronizer.ELEMENT_DISABLED_EVENT, this.disabledListener);
}
return removeViewport;
}();
_proto.getViewportByElement = function () {
function getViewportByElement(viewportElement) {
var length = this.syncedViewports.length;
for (var i = 0; i < length; i++) {
var viewport = this.syncedViewports[i];
if (viewport.element === viewportElement) {
return viewport;
}
}
}
return getViewportByElement;
}();
_proto.removeViewportByElement = function () {
function removeViewportByElement(viewportElement) {
var viewport = this.getViewportByElement(viewportElement);
if (viewport) {
this.removeViewport(viewport);
}
}
return removeViewportByElement;
}();
_proto.removeLinkedViewportFromSession = function () {
function removeLinkedViewportFromSession(viewport) {
var linkedViewports = Session.get('StackImagePositionOffsetSynchronizerLinkedViewports');
var index = linkedViewports.indexOf(viewport.index);
if (index !== -1) {
linkedViewports.splice(index, 1);
Session.set('StackImagePositionOffsetSynchronizerLinkedViewports', linkedViewports);
}
}
return removeLinkedViewportFromSession;
}();
_proto.elementDisabledHandler = function () {
function elementDisabledHandler(context) {
return function (e) {
return context.removeViewportByElement(e.detail.element);
};
}
return elementDisabledHandler;
}();
_proto.getViewportByIndexes = function () {
function getViewportByIndexes(viewportIndexes) {
var viewports = [];
var $viewportElements = $('.imageViewerViewport');
viewportIndexes.forEach(function (index) {
var element = $viewportElements.get(index);
if (!element) {
return;
}
viewports.push({
index: index,
element: element
});
});
return viewports;
}
return getViewportByIndexes;
}();
_proto.isViewportsLinkable = function () {
function isViewportsLinkable(viewportElementA, viewportElementB) {
var viewportAImageNormal = this.getViewportImageNormal(viewportElementA);
var viewportBImageNormal = this.getViewportImageNormal(viewportElementB);
if (viewportAImageNormal && viewportBImageNormal) {
var angleInRadians = viewportBImageNormal.angleTo(viewportAImageNormal); // Pi / 12 radians = 15 degrees
// If the angle between two vectors is Pi, it means they are just inverted
return angleInRadians < Math.PI / 12 || angleInRadians === Math.PI;
}
return false;
}
return isViewportsLinkable;
}();
_proto.getLinkableViewports = function () {
function getLinkableViewports() {
var _this2 = this;
var activeViewportElement = this.getActiveViewportElement();
var viewports = [];
$('.imageViewerViewport').each(function (index, viewportElement) {
if (_this2.isViewportsLinkable(activeViewportElement, viewportElement)) {
viewports.push({
index: index,
element: viewportElement
});
}
});
return viewports;
}
return getLinkableViewports;
}();
_proto.getViewportImageNormal = function () {
function getViewportImageNormal(element) {
if (!element) {
return;
}
element = $(element).get(0);
try {
var enabledElement = cornerstone.getEnabledElement(element);
if (!enabledElement.image) {
return;
}
var imageId = enabledElement.image.imageId;
var imagePlane = cornerstone.metaData.get('imagePlane', imageId);
if (!imagePlane || !imagePlane.rowCosines || !imagePlane.columnCosines) {
return;
}
return imagePlane.rowCosines.clone().cross(imagePlane.columnCosines);
} catch (error) {
var errorMessage = error.message || error;
OHIF.log.info("StackImagePositionOffsetSynchronizer getViewportImageNormal: " + errorMessage);
}
}
return getViewportImageNormal;
}();
(0, _createClass2.default)(StackImagePositionOffsetSynchronizer, null, [{
key: "ELEMENT_DISABLED_EVENT",
get: function () {
return 'cornerstoneelementdisabled.StackImagePositionOffsetSynchronizer';
}
}]);
return StackImagePositionOffsetSynchronizer;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"StudyLoadingListener.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/StudyLoadingListener.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
module.export({
StudyLoadingListener: function () {
return StudyLoadingListener;
},
StackLoadingListener: function () {
return StackLoadingListener;
},
DICOMFileLoadingListener: function () {
return DICOMFileLoadingListener;
}
});
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 0);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 1);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 2);
var cornerstone, cornerstoneWADOImageLoader;
module.watch(require("meteor/ohif:cornerstone"), {
cornerstone: function (v) {
cornerstone = v;
},
cornerstoneWADOImageLoader: function (v) {
cornerstoneWADOImageLoader = v;
}
}, 3);
var BaseLoadingListener =
/*#__PURE__*/
function () {
function BaseLoadingListener(stack, options) {
options = options || {};
this.id = BaseLoadingListener.getNewId();
this.stack = stack;
this.startListening();
this.statsItemsLimit = options.statsItemsLimit || 2;
this.stats = {
items: [],
total: 0,
elapsedTime: 0,
speed: 0
}; // Register the start point to make it possible to calculate
// bytes/s or frames/s when the first byte or frame is received
this._addStatsData(0); // Update the progress before starting the download
// to make it possible to update the UI
this._updateProgress();
}
var _proto = BaseLoadingListener.prototype;
_proto._addStatsData = function () {
function _addStatsData(value) {
var date = new Date();
var stats = this.stats;
var items = stats.items;
var newItem = {
value: value,
date: date
};
items.push(newItem);
stats.total += newItem.value; // Remove items until it gets below the limit
while (items.length > this.statsItemsLimit) {
var item = items.shift();
stats.total -= item.value;
} // Update the elapsedTime (seconds) based on first and last
// elements and recalculate the speed (bytes/s or frames/s)
if (items.length > 1) {
var oldestItem = items[0];
stats.elapsedTime = (newItem.date.getTime() - oldestItem.date.getTime()) / 1000;
stats.speed = (stats.total - oldestItem.value) / stats.elapsedTime;
}
}
return _addStatsData;
}();
_proto._getProgressSessionId = function () {
function _getProgressSessionId() {
var displaySetInstanceUid = this.stack.displaySetInstanceUid;
return 'StackProgress:' + displaySetInstanceUid;
}
return _getProgressSessionId;
}();
_proto._clearSession = function () {
function _clearSession() {
var progressSessionId = this._getProgressSessionId();
Session.set(progressSessionId, undefined);
delete Session.keys.progressSessionId;
}
return _clearSession;
}();
_proto.startListening = function () {
function startListening() {
throw new Error('`startListening` must be implemented by child clases');
}
return startListening;
}();
_proto.stopListening = function () {
function stopListening() {
throw new Error('`stopListening` must be implemented by child clases');
}
return stopListening;
}();
_proto.destroy = function () {
function destroy() {
this.stopListening();
this._clearSession();
}
return destroy;
}();
BaseLoadingListener.getNewId = function () {
function getNewId() {
var timeSlice = new Date().getTime().toString().slice(-8);
var randomNumber = parseInt(Math.random() * 1000000000);
return timeSlice.toString() + randomNumber.toString();
}
return getNewId;
}();
return BaseLoadingListener;
}();
var DICOMFileLoadingListener =
/*#__PURE__*/
function (_BaseLoadingListener) {
(0, _inheritsLoose2.default)(DICOMFileLoadingListener, _BaseLoadingListener);
function DICOMFileLoadingListener(stack) {
var _this;
_this = _BaseLoadingListener.call(this, stack) || this;
_this._dataSetUrl = _this._getDataSetUrl(stack);
_this._lastLoaded = 0; // Check how many instances has already been download (cached)
_this._checkCachedData();
return _this;
}
var _proto2 = DICOMFileLoadingListener.prototype;
_proto2._checkCachedData = function () {
function _checkCachedData() {
var dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(this._dataSetUrl);
if (dataSet) {
var dataSetLength = dataSet.byteArray.length;
this._updateProgress({
percentComplete: 100,
loaded: dataSetLength,
total: dataSetLength
});
}
}
return _checkCachedData;
}();
_proto2._getImageLoadProgressEventName = function () {
function _getImageLoadProgressEventName() {
return 'cornerstoneimageloadprogress.' + this.id;
}
return _getImageLoadProgressEventName;
}();
_proto2.startListening = function () {
function startListening() {
var imageLoadProgressEventName = this._getImageLoadProgressEventName();
var imageLoadProgressEventHandle = this._imageLoadProgressEventHandle.bind(this);
this.stopListening();
cornerstone.events.addEventListener(imageLoadProgressEventName, imageLoadProgressEventHandle);
}
return startListening;
}();
_proto2.stopListening = function () {
function stopListening() {
var imageLoadProgressEventName = this._getImageLoadProgressEventName();
cornerstone.events.removeEventListener(imageLoadProgressEventName);
}
return stopListening;
}();
_proto2._imageLoadProgressEventHandle = function () {
function _imageLoadProgressEventHandle(e) {
var eventData = e.detail;
var dataSetUrl = this._convertImageIdToDataSetUrl(eventData.imageId);
var bytesDiff = eventData.loaded - this._lastLoaded;
if (!this._dataSetUrl === dataSetUrl) {
return;
} // Add the bytes downloaded to the stats
this._addStatsData(bytesDiff); // Update the download progress
this._updateProgress(eventData); // Cache the last eventData.loaded value
this._lastLoaded = eventData.loaded;
}
return _imageLoadProgressEventHandle;
}();
_proto2._updateProgress = function () {
function _updateProgress(eventData) {
var progressSessionId = this._getProgressSessionId();
eventData = eventData || {};
Session.set(progressSessionId, {
multiFrame: false,
percentComplete: eventData.percentComplete,
bytesLoaded: eventData.loaded,
bytesTotal: eventData.total,
bytesPerSecond: this.stats.speed
});
}
return _updateProgress;
}();
_proto2._convertImageIdToDataSetUrl = function () {
function _convertImageIdToDataSetUrl(imageId) {
// Remove the prefix ("dicomweb:" or "wadouri:"")
imageId = imageId.replace(/^(dicomweb:|wadouri:)/i, ''); // Remove "frame=999&" from the imageId
imageId = imageId.replace(/frame=\d+&?/i, ''); // Remove the last "&" like in "http://...?foo=1&bar=2&"
imageId = imageId.replace(/&$/, '');
return imageId;
}
return _convertImageIdToDataSetUrl;
}();
_proto2._getDataSetUrl = function () {
function _getDataSetUrl(stack) {
var imageId = stack.imageIds[0];
return this._convertImageIdToDataSetUrl(imageId);
}
return _getDataSetUrl;
}();
return DICOMFileLoadingListener;
}(BaseLoadingListener);
var StackLoadingListener =
/*#__PURE__*/
function (_BaseLoadingListener2) {
(0, _inheritsLoose2.default)(StackLoadingListener, _BaseLoadingListener2);
function StackLoadingListener(stack) {
var _this2;
_this2 = _BaseLoadingListener2.call(this, stack, {
statsItemsLimit: 20
}) || this;
_this2.imageDataMap = _this2._convertImageIdsArrayToMap(stack.imageIds);
_this2.framesStatus = _this2._createArray(stack.imageIds.length, false);
_this2.loadedCount = 0; // Check how many instances has already been download (cached)
_this2._checkCachedData();
return _this2;
}
var _proto3 = StackLoadingListener.prototype;
_proto3._convertImageIdsArrayToMap = function () {
function _convertImageIdsArrayToMap(imageIds) {
var imageIdsMap = new Map();
for (var i = 0; i < imageIds.length; i++) {
imageIdsMap.set(imageIds[i], {
index: i,
loaded: false
});
}
return imageIdsMap;
}
return _convertImageIdsArrayToMap;
}();
_proto3._createArray = function () {
function _createArray(length, defaultValue) {
// `new Array(length)` is an anti-pattern in javascript because its
// funny API. Otherwise I would go for `new Array(length).fill(false)`
var array = [];
for (var i = 0; i < length; i++) {
array[i] = defaultValue;
}
return array;
}
return _createArray;
}();
_proto3._checkCachedData = function () {
function _checkCachedData() {// const imageIds = this.stack.imageIds;
// TODO: No way to check status of Promise.
/*for(let i = 0; i < imageIds.length; i++) {
const imageId = imageIds[i];
const imagePromise = cornerstone.imageCache.getImageLoadObject(imageId).promise;
if (imagePromise && (imagePromise.state() === 'resolved')) {
this._updateFrameStatus(imageId, true);
}
}*/
}
return _checkCachedData;
}();
_proto3._getImageLoadedEventName = function () {
function _getImageLoadedEventName() {
return 'cornerstoneimageloaded.' + this.id;
}
return _getImageLoadedEventName;
}();
_proto3._getImageCachePromiseRemoveEventName = function () {
function _getImageCachePromiseRemoveEventName() {
return 'cornerstoneimagecachepromiseremoved.' + this.id;
}
return _getImageCachePromiseRemoveEventName;
}();
_proto3.startListening = function () {
function startListening() {
var imageLoadedEventName = this._getImageLoadedEventName();
var imageCachePromiseRemovedEventName = this._getImageCachePromiseRemoveEventName();
var imageLoadedEventHandle = this._imageLoadedEventHandle.bind(this);
var imageCachePromiseRemovedEventHandle = this._imageCachePromiseRemovedEventHandle.bind(this);
this.stopListening();
cornerstone.events.addEventListener(imageLoadedEventName, imageLoadedEventHandle);
cornerstone.events.addEventListener(imageCachePromiseRemovedEventName, imageCachePromiseRemovedEventHandle);
}
return startListening;
}();
_proto3.stopListening = function () {
function stopListening() {
var imageLoadedEventName = this._getImageLoadedEventName();
var imageCachePromiseRemovedEventName = this._getImageCachePromiseRemoveEventName();
cornerstone.events.removeEventListener(imageLoadedEventName);
cornerstone.events.removeEventListener(imageCachePromiseRemovedEventName);
}
return stopListening;
}();
_proto3._updateFrameStatus = function () {
function _updateFrameStatus(imageId, loaded) {
var imageData = this.imageDataMap.get(imageId);
if (!imageData || imageData.loaded === loaded) {
return;
} // Add one more frame to the stats
if (loaded) {
this._addStatsData(1);
}
imageData.loaded = loaded;
this.framesStatus[imageData.index] = loaded;
this.loadedCount += loaded ? 1 : -1;
this._updateProgress();
}
return _updateFrameStatus;
}();
_proto3._imageLoadedEventHandle = function () {
function _imageLoadedEventHandle(e) {
this._updateFrameStatus(e.detail.image.imageId, true);
}
return _imageLoadedEventHandle;
}();
_proto3._imageCachePromiseRemovedEventHandle = function () {
function _imageCachePromiseRemovedEventHandle(e) {
this._updateFrameStatus(e.detail.imageId, false);
}
return _imageCachePromiseRemovedEventHandle;
}();
_proto3._updateProgress = function () {
function _updateProgress() {
var totalFramesCount = this.stack.imageIds.length;
var loadedFramesCount = this.loadedCount;
var loadingFramesCount = totalFramesCount - loadedFramesCount;
var percentComplete = Math.round(loadedFramesCount / totalFramesCount * 100);
var progressSessionId = this._getProgressSessionId();
Session.set(progressSessionId, {
multiFrame: true,
totalFramesCount: totalFramesCount,
loadedFramesCount: loadedFramesCount,
loadingFramesCount: loadingFramesCount,
percentComplete: percentComplete,
framesPerSecond: this.stats.speed,
framesStatus: this.framesStatus
});
}
return _updateProgress;
}();
_proto3._logProgress = function () {
function _logProgress() {
var totalFramesCount = this.stack.imageIds.length;
var displaySetInstanceUid = this.stack.displaySetInstanceUid;
var progressBar = '[';
for (var i = 0; i < totalFramesCount; i++) {
var ch = this.framesStatus[i] ? '|' : '.';
progressBar += "" + ch;
}
progressBar += ']';
OHIF.log.info(displaySetInstanceUid + ": " + progressBar);
}
return _logProgress;
}();
return StackLoadingListener;
}(BaseLoadingListener);
var StudyLoadingListener =
/*#__PURE__*/
function () {
function StudyLoadingListener() {
this.listeners = {};
}
var _proto4 = StudyLoadingListener.prototype;
_proto4.addStack = function () {
function addStack(stack, stackMetaData) {
var displaySetInstanceUid = stack.displaySetInstanceUid;
if (!this.listeners[displaySetInstanceUid]) {
var listener = this._createListener(stack, stackMetaData);
if (listener) {
this.listeners[displaySetInstanceUid] = listener;
}
}
}
return addStack;
}();
_proto4.addStudy = function () {
function addStudy(study) {
var _this3 = this;
study.displaySets.forEach(function (displaySet) {
var stack = OHIF.viewerbase.stackManager.findOrCreateStack(study, displaySet);
_this3.addStack(stack, {
isMultiFrame: displaySet.isMultiFrame
});
});
}
return addStudy;
}();
_proto4.addStudies = function () {
function addStudies(studies) {
if (!studies || !studies.length) {
return;
}
for (var i = 0; i < studies.length; i++) {
this.addStudy(studies[i]);
}
}
return addStudies;
}();
_proto4.clear = function () {
function clear() {
var displaySetInstanceUids = Object.keys(this.listeners);
var length = displaySetInstanceUids.length;
for (var i = 0; i < length; i++) {
var displaySetInstanceUid = displaySetInstanceUids[i];
var displaySet = this.listeners[displaySetInstanceUid];
displaySet.destroy();
}
this.listeners = {};
}
return clear;
}();
_proto4._createListener = function () {
function _createListener(stack, stackMetaData) {
var schema = this._getSchema(stack); // A StackLoadingListener can be created if it's wadors or not a multiframe
// wadouri instance (single file) that means "N" files will have to be
// downloaded where "N" is the number of frames. DICOMFileLoadingListener
// is created only if it's a single DICOM file and there's no way to know
// how many frames has already been loaded (bytes/s instead of frames/s).
if (schema === 'wadors' || !stackMetaData.isMultiFrame) {
return new StackLoadingListener(stack);
} else {
return new DICOMFileLoadingListener(stack);
}
}
return _createListener;
}();
_proto4._getSchema = function () {
function _getSchema(stack) {
var imageId = stack.imageIds[0];
var colonIndex = imageId.indexOf(':');
return imageId.substring(0, colonIndex);
}
return _getSchema;
}(); // Singleton
StudyLoadingListener.getInstance = function () {
function getInstance() {
if (!StudyLoadingListener._instance) {
StudyLoadingListener._instance = new StudyLoadingListener();
}
return StudyLoadingListener._instance;
}
return getInstance;
}();
return StudyLoadingListener;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"StudyMetadataSource.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/StudyMetadataSource.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
StudyMetadataSource: function () {
return StudyMetadataSource;
}
});
var OHIFError;
module.watch(require("./OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 0);
var StudyMetadataSource =
/*#__PURE__*/
function () {
function StudyMetadataSource() {}
var _proto = StudyMetadataSource.prototype;
/**
* Get study metadata for a study with given study InstanceUID.
* @param {String} studyInstanceUID Study InstanceUID.
*/
_proto.getByInstanceUID = function () {
function getByInstanceUID(studyInstanceUID) {
/**
* Please override this method on a specialized class.
*/
throw new OHIFError('StudyMetadataSource::getByInstanceUID is not overriden. Please, override it in a specialized class. See OHIFStudyMetadataSource for example');
}
return getByInstanceUID;
}();
/**
* Load study info and study metadata for a given study into the viewer.
* @param {StudySummary|StudyMetadata} study of StudySummary or StudyMetadata object.
*/
_proto.loadStudy = function () {
function loadStudy(study) {
/**
* Please override this method on a specialized class.
*/
throw new OHIFError('StudyMetadataSource::loadStudy is not overriden. Please, override it in a specialized class. See OHIFStudyMetadataSource for example');
}
return loadStudy;
}();
return StudyMetadataSource;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"StudyPrefetcher.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/StudyPrefetcher.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
StudyPrefetcher: function () {
return StudyPrefetcher;
}
});
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 1);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 2);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 3);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 4);
var OHIFError;
module.watch(require("./OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 5);
var StackManager;
module.watch(require("../StackManager.js"), {
StackManager: function (v) {
StackManager = v;
}
}, 6);
var getImageId;
module.watch(require("../getImageId.js"), {
getImageId: function (v) {
getImageId = v;
}
}, 7);
var StudyPrefetcher =
/*#__PURE__*/
function () {
function StudyPrefetcher(studies) {
this.studies = studies || [];
this.prefetchDisplaySetsTimeout = 300;
this.lastActiveViewportElement = null;
this.cacheFullHandlerBound = _.bind(this.cacheFullHandler, this);
cornerstone.events.addEventListener('cornerstoneimagecachefull.StudyPrefetcher', this.cacheFullHandlerBound);
}
var _proto = StudyPrefetcher.prototype;
_proto.destroy = function () {
function destroy() {
this.stopPrefetching();
cornerstone.events.removeEventListener('cornerstoneimagecachefull.StudyPrefetcher', this.cacheFullHandlerBound);
}
return destroy;
}();
StudyPrefetcher.getInstance = function () {
function getInstance() {
if (!StudyPrefetcher.instance) {
StudyPrefetcher.instance = new StudyPrefetcher();
}
return StudyPrefetcher.instance;
}
return getInstance;
}();
_proto.setStudies = function () {
function setStudies(studies) {
this.stopPrefetching();
this.studies = studies;
}
return setStudies;
}();
_proto.prefetch = function () {
function prefetch() {
if (!this.studies || !this.studies.length) {
return;
}
this.stopPrefetching();
this.prefetchActiveViewport();
this.prefetchDisplaySets();
}
return prefetch;
}();
_proto.stopPrefetching = function () {
function stopPrefetching() {
this.disableViewportPrefetch();
cornerstoneTools.requestPoolManager.clearRequestStack('prefetch');
}
return stopPrefetching;
}();
_proto.prefetchActiveViewport = function () {
function prefetchActiveViewport() {
var activeViewportElement = OHIF.viewerbase.viewportUtils.getActiveViewportElement();
this.enablePrefetchOnElement(activeViewportElement);
this.attachActiveViewportListeners(activeViewportElement);
}
return prefetchActiveViewport;
}();
_proto.disableViewportPrefetch = function () {
function disableViewportPrefetch() {
$('.imageViewerViewport').each(function () {
if (!$(this).find('canvas').length) {
return;
}
cornerstoneTools.stackPrefetch.disable(this);
});
}
return disableViewportPrefetch;
}();
_proto.hasStack = function () {
function hasStack(element) {
var stack = cornerstoneTools.getToolState(element, 'stack');
return stack && stack.data.length && stack.data[0].imageIds.length > 1;
}
return hasStack;
}();
/**
* This function enables stack prefetching for a specified element (viewport)
* It first disables any prefetching currently occurring on any other viewports.
*
* @param element {node} DOM Node representing the viewport element
*/
_proto.enablePrefetchOnElement = function () {
function enablePrefetchOnElement(element) {
if (!$(element).find('canvas').length) {
return;
} // Make sure there is a stack to fetch
if (this.hasStack(element)) {
// Check if this is a clip or not
var activeViewportIndex = Session.get('activeViewport');
var displaySetInstanceUid = OHIF.viewer.data.loadedSeriesData[activeViewportIndex].displaySetInstanceUid;
var stack = StackManager.findStack(displaySetInstanceUid);
if (!stack) {
throw new OHIFError("Requested stack " + displaySetInstanceUid + " was not created");
}
cornerstoneTools.stackPrefetch.enable(element);
}
}
return enablePrefetchOnElement;
}();
_proto.attachActiveViewportListeners = function () {
function attachActiveViewportListeners(activeViewportElement) {
function newImageHandler() {
// It needs to be called asynchronously because cornerstone does it at the same way.
// All instance urls to be prefetched will be removed again if we add them before
// Cornerstone callback (see stackPrefetch.onImageUpdated).
StudyPrefetcher.prefetchDisplaySetsAsync();
}
if (this.lastActiveViewportElement) {
this.lastActiveViewportElement.removeEventListener('cornerstonenewimage.StudyPrefetcher', newImageHandler);
}
activeViewportElement.removeEventListener('cornerstonenewimage.StudyPrefetcher', newImageHandler); // Cornerstone will not attach an event listener if the element doesn't have a stack
if (this.hasStack(activeViewportElement)) {
activeViewportElement.addEventListener('cornerstonenewimage.StudyPrefetcher', newImageHandler);
}
this.lastActiveViewportElement = activeViewportElement;
}
return attachActiveViewportListeners;
}();
_proto.prefetchDisplaySetsAsync = function () {
function prefetchDisplaySetsAsync(timeout) {
var _this = this;
timeout = timeout || this.prefetchDisplaySetsTimeout;
clearTimeout(this.prefetchDisplaySetsHandler);
this.prefetchDisplaySetsHandler = setTimeout(function () {
_this.prefetchDisplaySets();
}, timeout);
}
return prefetchDisplaySetsAsync;
}();
_proto.prefetchDisplaySets = function () {
function prefetchDisplaySets() {
var config;
if (Meteor.settings && Meteor.settings.public && Meteor.settings.prefetch) {
config = Meteor.settings.public.prefetch;
} else {
config = {
order: 'closest',
displaySetCount: 1
};
}
var displaySetsToPrefetch = this.getDisplaySetsToPrefetch(config);
var imageIds = this.getImageIdsFromDisplaySets(displaySetsToPrefetch);
this.prefetchImageIds(imageIds);
}
return prefetchDisplaySets;
}();
_proto.prefetchImageIds = function () {
function prefetchImageIds(imageIds) {
var nonCachedImageIds = this.filterCachedImageIds(imageIds);
var requestPoolManager = cornerstoneTools.requestPoolManager;
var requestType = 'prefetch';
var preventCache = false;
var noop = function () {};
nonCachedImageIds.forEach(function (imageId) {
requestPoolManager.addRequest({}, imageId, requestType, preventCache, noop, noop);
});
requestPoolManager.startGrabbing();
}
return prefetchImageIds;
}();
_proto.getActiveViewportImage = function () {
function getActiveViewportImage() {
var element = OHIF.viewerbase.viewportUtils.getActiveViewportElement();
if (!element) {
return;
}
var enabledElement = cornerstone.getEnabledElement(element);
var image = enabledElement.image;
return image;
}
return getActiveViewportImage;
}();
_proto.getStudy = function () {
function getStudy(image) {
var studyMetadata = cornerstone.metaData.get('study', image.imageId);
return OHIF.viewer.Studies.find(function (study) {
return study.studyInstanceUid === studyMetadata.studyInstanceUid;
});
}
return getStudy;
}();
_proto.getSeries = function () {
function getSeries(study, image) {
var seriesMetadata = cornerstone.metaData.get('series', image.imageId);
var studyMetadata = OHIF.viewerbase.getStudyMetadata(study);
return studyMetadata.getSeriesByUID(seriesMetadata.seriesInstanceUid);
}
return getSeries;
}();
_proto.getInstance = function () {
function getInstance(series, image) {
var instanceMetadata = cornerstone.metaData.get('instance', image.imageId);
return series.getInstanceByUID(instanceMetadata.sopInstanceUid);
}
return getInstance;
}();
_proto.getActiveDisplaySet = function () {
function getActiveDisplaySet(displaySets, instance) {
return _.find(displaySets, function (displaySet) {
return _.some(displaySet.images, function (displaySetImage) {
return displaySetImage.sopInstanceUid === instance.sopInstanceUid;
});
});
}
return getActiveDisplaySet;
}();
_proto.getDisplaySetsToPrefetch = function () {
function getDisplaySetsToPrefetch(config) {
var image = this.getActiveViewportImage();
if (!image || !config || !config.displaySetCount) {
return [];
}
var study = this.getStudy(image);
var series = this.getSeries(study, image);
var instance = this.getInstance(series, image);
var displaySets = study.displaySets;
var activeDisplaySet = this.getActiveDisplaySet(displaySets, instance);
var prefetchMethodMap = {
topdown: 'getFirstDisplaySets',
downward: 'getNextDisplaySets',
closest: 'getClosestDisplaySets'
};
var prefetchOrder = config.order;
var methodName = prefetchMethodMap[prefetchOrder];
var getDisplaySets = this[methodName];
if (!getDisplaySets) {
if (prefetchOrder) {
OHIF.log.warn("Invalid prefetch order configuration (" + prefetchOrder + ")");
}
return [];
}
return getDisplaySets.call(this, displaySets, activeDisplaySet, config.displaySetCount);
}
return getDisplaySetsToPrefetch;
}();
_proto.getFirstDisplaySets = function () {
function getFirstDisplaySets(displaySets, activeDisplaySet, displaySetCount) {
var length = displaySets.length;
var selectedDisplaySets = [];
for (var i = 0; i < length && displaySetCount; i++) {
var displaySet = displaySets[i];
if (displaySet !== activeDisplaySet) {
selectedDisplaySets.push(displaySet);
displaySetCount--;
}
}
return selectedDisplaySets;
}
return getFirstDisplaySets;
}();
_proto.getNextDisplaySets = function () {
function getNextDisplaySets(displaySets, activeDisplaySet, displaySetCount) {
var activeDisplaySetIndex = displaySets.indexOf(activeDisplaySet);
var begin = activeDisplaySetIndex + 1;
var end = Math.min(begin + displaySetCount, displaySets.length);
return displaySets.slice(begin, end);
}
return getNextDisplaySets;
}();
_proto.getClosestDisplaySets = function () {
function getClosestDisplaySets(displaySets, activeDisplaySet, displaySetCount) {
var activeDisplaySetIndex = displaySets.indexOf(activeDisplaySet);
var length = displaySets.length;
var selectedDisplaySets = [];
var left = activeDisplaySetIndex - 1;
var right = activeDisplaySetIndex + 1;
while ((left >= 0 || right < length) && displaySetCount) {
if (left >= 0) {
selectedDisplaySets.push(displaySets[left]);
displaySetCount--;
left--;
}
if (right < length && displaySetCount) {
selectedDisplaySets.push(displaySets[right]);
displaySetCount--;
right++;
}
}
return selectedDisplaySets;
}
return getClosestDisplaySets;
}();
_proto.getImageIdsFromDisplaySets = function () {
function getImageIdsFromDisplaySets(displaySets) {
var _this2 = this;
var imageIds = [];
displaySets.forEach(function (displaySet) {
imageIds = imageIds.concat(_this2.getImageIdsFromDisplaySet(displaySet));
});
return imageIds;
}
return getImageIdsFromDisplaySets;
}();
_proto.getImageIdsFromDisplaySet = function () {
function getImageIdsFromDisplaySet(displaySet) {
var imageIds = [];
displaySet.images.forEach(function (image) {
var numFrames = image.numFrames;
if (numFrames > 1) {
for (var i = 0; i < numFrames; i++) {
var imageId = getImageId(image, i);
imageIds.push(imageId);
}
} else {
var _imageId = getImageId(image);
imageIds.push(_imageId);
}
});
return imageIds;
}
return getImageIdsFromDisplaySet;
}();
_proto.filterCachedImageIds = function () {
function filterCachedImageIds(imageIds) {
var _this3 = this;
return _.filter(imageIds, function (imageId) {
return !_this3.isImageCached(imageId);
});
}
return filterCachedImageIds;
}();
_proto.isImageCached = function () {
function isImageCached(imageId) {
var image = cornerstone.imageCache.imageCache[imageId];
return image && image.sizeInBytes;
}
return isImageCached;
}();
_proto.cacheFullHandler = function () {
function cacheFullHandler() {
OHIF.log.warn('Cache full');
this.stopPrefetching();
}
return cacheFullHandler;
}();
return StudyPrefetcher;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"TypeSafeCollection.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/TypeSafeCollection.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
module.export({
TypeSafeCollection: function () {
return TypeSafeCollection;
}
});
var Random;
module.watch(require("meteor/random"), {
Random: function (v) {
Random = v;
}
}, 0);
var ReactiveVar;
module.watch(require("meteor/reactive-var"), {
ReactiveVar: function (v) {
ReactiveVar = v;
}
}, 1);
/**
* Constants
*/
var PROPERTY_SEPARATOR = '.';
var ORDER_ASC = 'asc';
var ORDER_DESC = 'desc';
var MIN_COUNT = 0x00000000;
var MAX_COUNT = 0x7FFFFFFF;
/**
* Class Definition
*/
var TypeSafeCollection =
/*#__PURE__*/
function () {
function TypeSafeCollection() {
this._operationCount = new ReactiveVar(MIN_COUNT);
this._elementList = [];
this._handlers = Object.create(null);
}
/**
* Private Methods
*/
var _proto = TypeSafeCollection.prototype;
_proto._invalidate = function () {
function _invalidate() {
var count = this._operationCount.get();
this._operationCount.set(count < MAX_COUNT ? count + 1 : MIN_COUNT);
}
return _invalidate;
}();
_proto._elements = function () {
function _elements(silent) {
silent === true || this._operationCount.get();
return this._elementList;
}
return _elements;
}();
_proto._elementWithPayload = function () {
function _elementWithPayload(payload, silent) {
return this._elements(silent).find(function (item) {
return item.payload === payload;
});
}
return _elementWithPayload;
}();
_proto._elementWithId = function () {
function _elementWithId(id, silent) {
return this._elements(silent).find(function (item) {
return item.id === id;
});
}
return _elementWithId;
}();
_proto._trigger = function () {
function _trigger(event, data) {
var handlers = this._handlers;
if (event in handlers) {
handlers = handlers[event];
if (!(handlers instanceof Array)) {
return;
}
for (var i = 0, limit = handlers.length; i < limit; ++i) {
var handler = handlers[i];
if (_isFunction(handler)) {
handler.call(null, data);
}
}
}
}
return _trigger;
}();
/**
* Public Methods
*/
_proto.onInsert = function () {
function onInsert(callback) {
if (_isFunction(callback)) {
var handlers = this._handlers.insert;
if (!(handlers instanceof Array)) {
handlers = [];
this._handlers.insert = handlers;
}
handlers.push(callback);
}
}
return onInsert;
}();
/**
* Update the payload associated with the given ID to be the new supplied payload.
* @param {string} id The ID of the entry that will be updated.
* @param {any} payload The element that will replace the previous payload.
* @returns {boolean} Returns true if the given ID is present in the collection, false otherwise.
*/
_proto.updateById = function () {
function updateById(id, payload) {
var result = false,
found = this._elementWithPayload(payload, true);
if (found) {
// nothing to do since the element is already in the collection...
if (found.id === id) {
// set result to true since the ids match...
result = true;
this._invalidate();
}
} else {
found = this._elementWithId(id, true);
if (found) {
found.payload = payload;
result = true;
this._invalidate();
}
}
return result;
}
return updateById;
}();
/**
* Signal that the given element has been changed by notifying reactive data-source observers.
* This method is basically a means to invalidate the inernal reactive data-source.
* @param {any} payload The element that has been altered.
* @returns {boolean} Returns true if the element is present in the collection, false otherwise.
*/
_proto.update = function () {
function update(payload) {
var result = false,
found = this._elementWithPayload(payload, true);
if (found) {
// nothing to do since the element is already in the collection...
result = true;
this._invalidate();
}
return result;
}
return update;
}();
/**
* Insert an element in the collection. On success, the element ID (a unique string) is returned. On failure, returns null.
* A failure scenario only happens when the given payload is already present in the collection. Note that NO exceptions are thrown!
* @param {any} payload The element to be stored.
* @returns {string} The ID of the inserted element or null if the element already exists...
*/
_proto.insert = function () {
function insert(payload) {
var id = null,
found = this._elementWithPayload(payload, true);
if (!found) {
id = Random.id();
this._elements(true).push({
id: id,
payload: payload
});
this._invalidate();
this._trigger('insert', {
id: id,
data: payload
});
}
return id;
}
return insert;
}();
/**
* Remove all elements from the collection.
* @returns {void} No meaningful value is returned.
*/
_proto.removeAll = function () {
function removeAll() {
var all = this._elements(true),
length = all.length;
for (var i = length - 1; i >= 0; i--) {
var item = all[i];
delete item.id;
delete item.payload;
all[i] = null;
}
all.splice(0, length);
this._invalidate();
}
return removeAll;
}();
/**
* Remove elements from the collection that match the criteria given in the property map.
* @param {Object} propertyMap A property map that will be macthed against all collection elements.
* @returns {Array} A list with all removed elements.
*/
_proto.remove = function () {
function remove(propertyMap) {
var found = this.findAllEntriesBy(propertyMap),
foundCount = found.length,
removed = [];
if (foundCount > 0) {
var _all = this._elements(true);
for (var i = foundCount - 1; i >= 0; i--) {
var item = found[i];
_all.splice(item[2], 1);
removed.push(item[0]);
}
this._invalidate();
}
return removed;
}
return remove;
}();
/**
* Provides the ID of the given element inside the collection.
* @param {any} payload The element being searched for.
* @returns {string} The ID of the given element or undefined if the element is not present.
*/
_proto.getElementId = function () {
function getElementId(payload) {
var found = this._elementWithPayload(payload);
return found && found.id;
}
return getElementId;
}();
/**
* Provides the position of the given element in the internal list returning -1 if the element is not present.
* @param {any} payload The element being searched for.
* @returns {number} The position of the given element in the internal list. If the element is not present -1 is returned.
*/
_proto.findById = function () {
function findById(id) {
var found = this._elementWithId(id);
return found && found.payload;
}
return findById;
}();
/**
* Provides the position of the given element in the internal list returning -1 if the element is not present.
* @param {any} payload The element being searched for.
* @returns {number} The position of the given element in the internal list. If the element is not present -1 is returned.
*/
_proto.indexOfElement = function () {
function indexOfElement(payload) {
return this._elements().indexOf(this._elementWithPayload(payload, true));
}
return indexOfElement;
}();
/**
* Provides the position of the element associated with the given ID in the internal list returning -1 if the element is not present.
* @param {string} id The index of the element.
* @returns {number} The position of the element associated with the given ID in the internal list. If the element is not present -1 is returned.
*/
_proto.indexOfId = function () {
function indexOfId(id) {
return this._elements().indexOf(this._elementWithId(id, true));
}
return indexOfId;
}();
/**
* Provides a list-like approach to the collection returning an element by index.
* @param {number} index The index of the element.
* @returns {any} If out of bounds, undefined is returned. Otherwise the element in the given position is returned.
*/
_proto.getElementByIndex = function () {
function getElementByIndex(index) {
var found = this._elements()[index >= 0 ? index : -1];
return found && found.payload;
}
return getElementByIndex;
}();
/**
* Find an element by a criteria defined by the given callback function.
* Attention!!! The reactive source will not be notified if no valid callback is supplied...
* @param {function} callback A callback function which will define the search criteria. The callback
* function will be passed the collection element, its ID and its index in this very order. The callback
* shall return true when its criterea has been fulfilled.
* @returns {any} The matched element or undefined if not match was found.
*/
_proto.find = function () {
function find(callback) {
var _this = this;
var found;
if (_isFunction(callback)) {
found = this._elements().find(function (item, index) {
return callback.call(_this, item.payload, item.id, index);
});
}
return found && found.payload;
}
return find;
}();
/**
* Find the first element that strictly matches the specified property map.
* @param {Object} propertyMap A property map that will be macthed against all collection elements.
* @param {Object} options A set of options. Currently only "options.sort" option is supported.
* @param {Object.SortingSpecifier} options.sort An optional sorting specifier. If a sorting specifier is supplied
* but is not valid, an exception will be thrown.
* @returns {Any} The matched element or undefined if not match was found.
*/
_proto.findBy = function () {
function findBy(propertyMap, options) {
var found;
if (_isObject(options)) {
// if the "options" argument is provided and is a valid object,
// it must be applied to the dataset before search...
var _all2 = this.all(options);
if (_all2.length > 0) {
if (_isObject(propertyMap)) {
found = _all2.find(function (item) {
return _compareToPropertyMapStrict(propertyMap, item);
});
} else {
found = _all2[0]; // simply extract the first element...
}
}
} else if (_isObject(propertyMap)) {
found = this._elements().find(function (item) {
return _compareToPropertyMapStrict(propertyMap, item.payload);
});
if (found) {
found = found.payload;
}
}
return found;
}
return findBy;
}();
/**
* Find all elements that strictly match the specified property map.
* Attention!!! The reactive source will not be notified if no valid property map is supplied...
* @param {Object} propertyMap A property map that will be macthed against all collection elements.
* @returns {Array} An array of entries of all elements that match the given criteria. Each set in
* in the array has the following format: [ elementData, elementId, elementIndex ].
*/
_proto.findAllEntriesBy = function () {
function findAllEntriesBy(propertyMap) {
var found = [];
if (_isObject(propertyMap)) {
this._elements().forEach(function (item, index) {
if (_compareToPropertyMapStrict(propertyMap, item.payload)) {
// Match! Add it to the found list...
found.push([item.payload, item.id, index]);
}
});
}
return found;
}
return findAllEntriesBy;
}();
/**
* Find all elements that match a specified property map.
* Attention!!! The reactive source will not be notified if no valid property map is supplied...
* @param {Object} propertyMap A property map that will be macthed against all collection elements.
* @param {Object} options A set of options. Currently only "options.sort" option is supported.
* @param {Object.SortingSpecifier} options.sort An optional sorting specifier. If a sorting specifier is supplied
* but is not valid, an exception will be thrown.
* @returns {Array} An array with all elements that match the given criteria and sorted in the specified sorting order.
*/
_proto.findAllBy = function () {
function findAllBy(propertyMap, options) {
var found = this.findAllEntriesBy(propertyMap).map(function (item) {
return item[0];
}); // Only payload is relevant...
if (_isObject(options)) {
if ('sort' in options) {
_sortListBy(found, options.sort);
}
}
return found;
}
return findAllBy;
}();
/**
* Executes the supplied callback function for each element of the collection.
* Attention!!! The reactive source will not be notified if no valid property map is supplied...
* @param {function} callback The callback function to be executed. The callback is passed the element,
* its ID and its index in this very order.
* @returns {void} Nothing is returned.
*/
_proto.forEach = function () {
function forEach(callback) {
var _this2 = this;
if (_isFunction(callback)) {
this._elements().forEach(function (item, index) {
callback.call(_this2, item.payload, item.id, index);
});
}
}
return forEach;
}();
/**
* Count the number of elements currently in the collection.
* @returns {number} The current number of elements in the collection.
*/
_proto.count = function () {
function count() {
return this._elements().length;
}
return count;
}();
/**
* Returns a list with all elements of the collection optionally sorted by a sorting specifier criteria.
* @param {Object} options A set of options. Currently only "options.sort" option is supported.
* @param {Object.SortingSpecifier} options.sort An optional sorting specifier. If a sorting specifier is supplied
* but is not valid, an exception will be thrown.
* @returns {Array} An array with all elements stored in the collection.
*/
_proto.all = function () {
function all(options) {
var list = this._elements().map(function (item) {
return item.payload;
});
if (_isObject(options)) {
if ('sort' in options) {
_sortListBy(list, options.sort);
}
}
return list;
}
return all;
}();
return TypeSafeCollection;
}();
/**
* Utility Functions
*/
/**
* Test if supplied argument is a valid object for current class purposes.
* Atention! The underscore version of this function should not be used for performance reasons.
*/
function _isObject(subject) {
return subject instanceof Object || (0, _typeof2.default)(subject) === 'object' && subject !== null;
}
/**
* Test if supplied argument is a valid string for current class purposes.
* Atention! The underscore version of this function should not be used for performance reasons.
*/
function _isString(subject) {
return typeof subject === 'string';
}
/**
* Test if supplied argument is a valid function for current class purposes.
* Atention! The underscore version of this function should not be used for performance reasons.
*/
function _isFunction(subject) {
return typeof subject === 'function';
}
/**
* Shortcut for Object's prototype "hasOwnProperty" method.
*/
var _hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* Retrieve an object's property value by name. Composite property names (e.g., 'address.country.name') are accepted.
* @param {Object} targetObject The object we want read the property from...
* @param {String} propertyName The property to be read (e.g., 'address.street.name' or 'address.street.number'
* to read object.address.street.name or object.address.street.number, respectively);
* @returns {Any} Returns whatever the property holds or undefined if the property cannot be read or reached.
*/
function _getPropertyValue(targetObject, propertyName) {
var propertyValue; // undefined (the default return value)
if (_isObject(targetObject) && _isString(propertyName)) {
var fragments = propertyName.split(PROPERTY_SEPARATOR);
var fragmentCount = fragments.length;
if (fragmentCount > 0) {
var firstFragment = fragments[0];
var remainingFragments = fragmentCount > 1 ? fragments.slice(1).join(PROPERTY_SEPARATOR) : null;
propertyValue = targetObject[firstFragment];
if (remainingFragments !== null) {
propertyValue = _getPropertyValue(propertyValue, remainingFragments);
}
}
}
return propertyValue;
}
/**
* Compare a property map with a target object using strict comparison.
* @param {Object} propertyMap The property map whose properties will be used for comparison. Composite
* property names (e.g., 'address.country.name') will be tested against the "resolved" properties from the target object.
* @param {Object} targetObject The target object whose properties will be tested.
* @returns {boolean} Returns true if the properties match, false otherwise.
*/
function _compareToPropertyMapStrict(propertyMap, targetObject) {
var result = false; // "for in" loops do not thown exceptions for invalid data types...
for (var propertyName in meteorBabelHelpers.sanitizeForInObject(propertyMap)) {
if (_hasOwnProperty.call(propertyMap, propertyName)) {
if (propertyMap[propertyName] !== _getPropertyValue(targetObject, propertyName)) {
result = false;
break;
} else if (result !== true) {
result = true;
}
}
}
return result;
}
/**
* Checks if a sorting specifier is valid.
* A valid sorting specifier consists of an array of arrays being each subarray a pair
* in the format ["property name", "sorting order"].
* The following exemple can be used to sort studies by "date"" and use "time" to break ties in descending order.
* [ [ 'study.date', 'desc' ], [ 'study.time', 'desc' ] ]
* @param {Array} specifiers The sorting specifier to be tested.
* @returns {boolean} Returns true if the specifiers are valid, false otherwise.
*/
function _isValidSortingSpecifier(specifiers) {
var result = true;
if (specifiers instanceof Array && specifiers.length > 0) {
for (var i = specifiers.length - 1; i >= 0; i--) {
var item = specifiers[i];
if (item instanceof Array) {
var property = item[0];
var order = item[1];
if (_isString(property) && (order === ORDER_ASC || order === ORDER_DESC)) {
continue;
}
}
result = false;
break;
}
}
return result;
}
/**
* Sorts an array based on sorting specifier options.
* @param {Array} list The that needs to be sorted.
* @param {Array} specifiers An array of specifiers. Please read isValidSortingSpecifier method definition for further details.
* @returns {void} No value is returned. The array is sorted in place.
*/
function _sortListBy(list, specifiers) {
if (list instanceof Array && _isValidSortingSpecifier(specifiers)) {
var specifierCount = specifiers.length;
list.sort(function () {
function _sortListByCallback(a, b) {
// callback name for stack traces...
var index = 0;
while (index < specifierCount) {
var specifier = specifiers[index];
var property = specifier[0];
var order = specifier[1] === ORDER_DESC ? -1 : 1;
var aValue = _getPropertyValue(a, property);
var bValue = _getPropertyValue(b, property); // @TODO: should we check for the types being compared, like:
// ~~ if (typeof aValue !== typeof bValue) continue;
// Not sure because dates, for example, can be correctly compared to numbers...
if (aValue < bValue) {
return order * -1;
}
if (aValue > bValue) {
return order * 1;
}
if (++index >= specifierCount) {
return 0;
}
}
}
return _sortListByCallback;
}());
} else {
throw new Error('Invalid Arguments');
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"metadata":{"InstanceMetadata.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/metadata/InstanceMetadata.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
module.export({
InstanceMetadata: function () {
return InstanceMetadata;
}
});
var Metadata;
module.watch(require("./Metadata"), {
Metadata: function (v) {
Metadata = v;
}
}, 0);
var OHIFError;
module.watch(require("../OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 1);
/**
* ATTENTION! This class should never depend on StudyMetadata or SeriesMetadata classes as this could
* possibly cause circular dependency issues.
*/
var UNDEFINED = 'undefined';
var NUMBER = 'number';
var STRING = 'string';
var STUDY_INSTANCE_UID = 'x0020000d';
var SERIES_INSTANCE_UID = 'x0020000e';
var InstanceMetadata =
/*#__PURE__*/
function (_Metadata) {
(0, _inheritsLoose2.default)(InstanceMetadata, _Metadata);
function InstanceMetadata(data, uid) {
var _this;
_this = _Metadata.call(this, data, uid) || this; // Initialize Private Properties
Object.defineProperties((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), {
_sopInstanceUID: {
configurable: true,
// configurable so that it can be redefined in sub-classes...
enumerable: false,
writable: true,
value: null
},
_imageId: {
configurable: true,
// configurable so that it can be redefined in sub-classes...
enumerable: false,
writable: true,
value: null
}
}); // Initialize Public Properties
_this._definePublicProperties();
return _this;
}
/**
* Private Methods
*/
/**
* Define Public Properties
* This method should only be called during initialization (inside the class constructor)
*/
var _proto = InstanceMetadata.prototype;
_proto._definePublicProperties = function () {
function _definePublicProperties() {
/**
* Property: this.sopInstanceUID
* Same as this.getSOPInstanceUID()
* It's specially useful in contexts where a method call is not suitable like in search criteria. For example:
* sopInstanceCollection.findBy({
* sopInstanceUID: '1.2.3.4.5.6.77777.8888888.99999999999.0'
* });
*/
Object.defineProperty(this, 'sopInstanceUID', {
configurable: false,
enumerable: false,
get: function () {
return this.getSOPInstanceUID();
}
});
}
return _definePublicProperties;
}();
/**
* Public Methods
*/
/**
* Returns the StudyInstanceUID of the current instance. This method is basically a shorthand the full "getTagValue" method call.
*/
_proto.getStudyInstanceUID = function () {
function getStudyInstanceUID() {
return this.getTagValue(STUDY_INSTANCE_UID, null);
}
return getStudyInstanceUID;
}();
/**
* Returns the SeriesInstanceUID of the current instance. This method is basically a shorthand the full "getTagValue" method call.
*/
_proto.getSeriesInstanceUID = function () {
function getSeriesInstanceUID() {
return this.getTagValue(SERIES_INSTANCE_UID, null);
}
return getSeriesInstanceUID;
}();
/**
* Returns the SOPInstanceUID of the current instance.
*/
_proto.getSOPInstanceUID = function () {
function getSOPInstanceUID() {
return this._sopInstanceUID;
}
return getSOPInstanceUID;
}(); // @TODO: Improve this... (E.g.: blob data)
_proto.getStringValue = function () {
function getStringValue(tagOrProperty, index, defaultValue) {
var value = this.getTagValue(tagOrProperty, defaultValue);
if ((0, _typeof2.default)(value) !== STRING && (0, _typeof2.default)(value) !== UNDEFINED) {
value = value.toString();
}
return InstanceMetadata.getIndexedValue(value, index, defaultValue);
}
return getStringValue;
}(); // @TODO: Improve this... (E.g.: blob data)
_proto.getFloatValue = function () {
function getFloatValue(tagOrProperty, index, defaultValue) {
var value = this.getTagValue(tagOrProperty, defaultValue);
value = InstanceMetadata.getIndexedValue(value, index, defaultValue);
if (value instanceof Array) {
value.forEach(function (val, idx) {
value[idx] = parseFloat(val);
});
return value;
}
return (0, _typeof2.default)(value) === STRING ? parseFloat(value) : value;
}
return getFloatValue;
}(); // @TODO: Improve this... (E.g.: blob data)
_proto.getIntValue = function () {
function getIntValue(tagOrProperty, index, defaultValue) {
var value = this.getTagValue(tagOrProperty, defaultValue);
value = InstanceMetadata.getIndexedValue(value, index, defaultValue);
if (value instanceof Array) {
value.forEach(function (val, idx) {
value[idx] = parseFloat(val);
});
return value;
}
return (0, _typeof2.default)(value) === STRING ? parseInt(value) : value;
}
return getIntValue;
}();
/**
* @deprecated Please use getTagValue instead.
*/
_proto.getRawValue = function () {
function getRawValue(tagOrProperty, defaultValue) {
return this.getTagValue(tagOrProperty, defaultValue);
}
return getRawValue;
}();
/**
* This function should be overriden by specialized classes in order to allow client libraries or viewers to take advantage of the Study Metadata API.
*/
_proto.getTagValue = function () {
function getTagValue(tagOrProperty, defaultValue) {
/**
* Please override this method on a specialized class.
*/
throw new OHIFError('InstanceMetadata::getTagValue is not overriden. Please, override it in a specialized class. See OHIFInstanceMetadata for example');
}
return getTagValue;
}();
/**
* Compares the current instance with another one.
* @param {InstanceMetadata} instance An instance of the InstanceMetadata class.
* @returns {boolean} Returns true if both instances refer to the same instance.
*/
_proto.equals = function () {
function equals(instance) {
var self = this;
return instance === self || instance instanceof InstanceMetadata && instance.getSOPInstanceUID() === self.getSOPInstanceUID();
}
return equals;
}();
/**
* Check if the tagOrProperty exists
* @param {String} tagOrProperty tag or property be checked
* @return {Boolean} True if the tag or property exists or false if doesn't
*/
_proto.tagExists = function () {
function tagExists(tagOrProperty) {
/**
* Please override this method
*/
throw new OHIFError('InstanceMetadata::tagExists is not overriden. Please, override it in a specialized class. See OHIFInstanceMetadata for example');
}
return tagExists;
}();
/**
* Get custom image id of a sop instance
* @return {Any} sop instance image id
*/
_proto.getImageId = function () {
function getImageId(frame) {
/**
* Please override this method
*/
throw new OHIFError('InstanceMetadata::getImageId is not overriden. Please, override it in a specialized class. See OHIFInstanceMetadata for example');
}
return getImageId;
}();
/**
* Static Methods
*/
/**
* Get an value based that can be index based. This function is called by all getters. See above functions.
* - If value is a String and has indexes:
* - If undefined index: returns an array of the split values.
* - If defined index:
* - If invalid: returns defaultValue
* - If valid: returns the indexed value
* - If value is not a String, returns default value.
*/
InstanceMetadata.getIndexedValue = function () {
function getIndexedValue(value, index, defaultValue) {
var result = defaultValue;
if ((0, _typeof2.default)(value) === STRING) {
var hasIndexValues = value.indexOf('\\') !== -1;
result = value;
if (hasIndexValues) {
var splitValues = value.split('\\');
if (Metadata.isValidIndex(index)) {
var indexedValue = splitValues[index];
result = (0, _typeof2.default)(indexedValue) !== STRING ? defaultValue : indexedValue;
} else {
result = splitValues;
}
}
}
return result;
}
return getIndexedValue;
}();
return InstanceMetadata;
}(Metadata);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"Metadata.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/metadata/Metadata.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
module.export({
Metadata: function () {
return Metadata;
}
});
/**
* Constants
*/
var STRING = 'string';
var NUMBER = 'number';
var FUNCTION = 'function';
var OBJECT = 'object';
/**
* Class Definition
*/
var Metadata =
/*#__PURE__*/
function () {
/**
* Constructor and Instance Methods
*/
function Metadata(data, uid) {
// Define the main "_data" private property as an immutable property.
// IMPORTANT: This property can only be set during instance construction.
Object.defineProperty(this, '_data', {
configurable: false,
enumerable: false,
writable: false,
value: data
}); // Define the main "_uid" private property as an immutable property.
// IMPORTANT: This property can only be set during instance construction.
Object.defineProperty(this, '_uid', {
configurable: false,
enumerable: false,
writable: false,
value: uid
}); // Define "_custom" properties as an immutable property.
// IMPORTANT: This property can only be set during instance construction.
Object.defineProperty(this, '_custom', {
configurable: false,
enumerable: false,
writable: false,
value: Object.create(null)
});
}
var _proto = Metadata.prototype;
_proto.getData = function () {
function getData() {
return this._data;
}
return getData;
}();
_proto.getDataProperty = function () {
function getDataProperty(propertyName) {
var propertyValue;
var _data = this._data;
if (_data instanceof Object || (0, _typeof2.default)(_data) === OBJECT && _data !== null) {
propertyValue = _data[propertyName];
}
return propertyValue;
}
return getDataProperty;
}();
/**
* Get unique object ID
*/
_proto.getObjectID = function () {
function getObjectID() {
return this._uid;
}
return getObjectID;
}();
/**
* Set custom attribute value
* @param {String} attribute Custom attribute name
* @param {Any} value Custom attribute value
*/
_proto.setCustomAttribute = function () {
function setCustomAttribute(attribute, value) {
this._custom[attribute] = value;
}
return setCustomAttribute;
}();
/**
* Get custom attribute value
* @param {String} attribute Custom attribute name
* @return {Any} Custom attribute value
*/
_proto.getCustomAttribute = function () {
function getCustomAttribute(attribute) {
return this._custom[attribute];
}
return getCustomAttribute;
}();
/**
* Check if a custom attribute exists
* @param {String} attribute Custom attribute name
* @return {Boolean} True if custom attribute exists or false if not
*/
_proto.customAttributeExists = function () {
function customAttributeExists(attribute) {
return attribute in this._custom;
}
return customAttributeExists;
}();
/**
* Set custom attributes in batch mode.
* @param {Object} attributeMap An object whose own properties will be used as custom attributes.
*/
_proto.setCustomAttributes = function () {
function setCustomAttributes(attributeMap) {
var _hasOwn = Object.prototype.hasOwnProperty;
var _custom = this._custom;
for (var attribute in meteorBabelHelpers.sanitizeForInObject(attributeMap)) {
if (_hasOwn.call(attributeMap, attribute)) {
_custom[attribute] = attributeMap[attribute];
}
}
}
return setCustomAttributes;
}();
/**
* Static Methods
*/
Metadata.isValidUID = function () {
function isValidUID(uid) {
return (0, _typeof2.default)(uid) === STRING && uid.length > 0;
}
return isValidUID;
}();
Metadata.isValidIndex = function () {
function isValidIndex(index) {
return (0, _typeof2.default)(index) === NUMBER && index >= 0 && (index | 0) === index;
}
return isValidIndex;
}();
Metadata.isValidCallback = function () {
function isValidCallback(callback) {
return (0, _typeof2.default)(callback) === FUNCTION;
}
return isValidCallback;
}();
return Metadata;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"SeriesMetadata.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/metadata/SeriesMetadata.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
module.export({
SeriesMetadata: function () {
return SeriesMetadata;
}
});
var Metadata;
module.watch(require("./Metadata"), {
Metadata: function (v) {
Metadata = v;
}
}, 0);
var InstanceMetadata;
module.watch(require("./InstanceMetadata"), {
InstanceMetadata: function (v) {
InstanceMetadata = v;
}
}, 1);
var SeriesMetadata =
/*#__PURE__*/
function (_Metadata) {
(0, _inheritsLoose2.default)(SeriesMetadata, _Metadata);
function SeriesMetadata(data, uid) {
var _this;
_this = _Metadata.call(this, data, uid) || this; // Initialize Private Properties
Object.defineProperties((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), {
_seriesInstanceUID: {
configurable: true,
// configurable so that it can be redefined in sub-classes...
enumerable: false,
writable: true,
value: null
},
_instances: {
configurable: false,
enumerable: false,
writable: false,
value: []
},
_firstInstance: {
configurable: false,
enumerable: false,
writable: true,
value: null
}
}); // Initialize Public Properties
_this._definePublicProperties();
return _this;
}
/**
* Private Methods
*/
/**
* Define Public Properties
* This method should only be called during initialization (inside the class constructor)
*/
var _proto = SeriesMetadata.prototype;
_proto._definePublicProperties = function () {
function _definePublicProperties() {
/**
* Property: this.seriesInstanceUID
* Same as this.getSeriesInstanceUID()
* It's specially useful in contexts where a method call is not suitable like in search criteria. For example:
* seriesCollection.findBy({
* seriesInstanceUID: '1.2.3.4.5.6.77777.8888888.99999999999.0'
* });
*/
Object.defineProperty(this, 'seriesInstanceUID', {
configurable: false,
enumerable: false,
get: function () {
return this.getSeriesInstanceUID();
}
});
}
return _definePublicProperties;
}();
/**
* Public Methods
*/
/**
* Returns the SeriesInstanceUID of the current series.
*/
_proto.getSeriesInstanceUID = function () {
function getSeriesInstanceUID() {
return this._seriesInstanceUID;
}
return getSeriesInstanceUID;
}();
/**
* Append an instance to the current series.
* @param {InstanceMetadata} instance The instance to be added to the current series.
* @returns {boolean} Returns true on success, false otherwise.
*/
_proto.addInstance = function () {
function addInstance(instance) {
var result = false;
if (instance instanceof InstanceMetadata && this.getInstanceByUID(instance.getSOPInstanceUID()) === void 0) {
this._instances.push(instance);
result = true;
}
return result;
}
return addInstance;
}();
/**
* Get the first instance of the current series retaining a consistent result across multiple calls.
* @return {InstanceMetadata} An instance of the InstanceMetadata class or null if it does not exist.
*/
_proto.getFirstInstance = function () {
function getFirstInstance() {
var instance = this._firstInstance;
if (!(instance instanceof InstanceMetadata)) {
instance = null;
var found = this.getInstanceByIndex(0);
if (found instanceof InstanceMetadata) {
this._firstInstance = found;
instance = found;
}
}
return instance;
}
return getFirstInstance;
}();
/**
* Find an instance by index.
* @param {number} index An integer representing a list index.
* @returns {InstanceMetadata} Returns a InstanceMetadata instance when found or undefined otherwise.
*/
_proto.getInstanceByIndex = function () {
function getInstanceByIndex(index) {
var found; // undefined by default...
if (Metadata.isValidIndex(index)) {
found = this._instances[index];
}
return found;
}
return getInstanceByIndex;
}();
/**
* Find an instance by SOPInstanceUID.
* @param {string} uid An UID string.
* @returns {InstanceMetadata} Returns a InstanceMetadata instance when found or undefined otherwise.
*/
_proto.getInstanceByUID = function () {
function getInstanceByUID(uid) {
var found; // undefined by default...
if (Metadata.isValidUID(uid)) {
found = this._instances.find(function (instance) {
return instance.getSOPInstanceUID() === uid;
});
}
return found;
}
return getInstanceByUID;
}();
/**
* Retrieve the number of instances within the current series.
* @returns {number} The number of instances in the current series.
*/
_proto.getInstanceCount = function () {
function getInstanceCount() {
return this._instances.length;
}
return getInstanceCount;
}();
/**
* Invokes the supplied callback for each instance in the current series passing
* two arguments: instance (an InstanceMetadata instance) and index (the integer
* index of the instance within the current series)
* @param {function} callback The callback function which will be invoked for each instance in the series.
* @returns {undefined} Nothing is returned.
*/
_proto.forEachInstance = function () {
function forEachInstance(callback) {
if (Metadata.isValidCallback(callback)) {
this._instances.forEach(function (instance, index) {
callback.call(null, instance, index);
});
}
}
return forEachInstance;
}();
/**
* Find the index of an instance inside the series.
* @param {InstanceMetadata} instance An instance of the SeriesMetadata class.
* @returns {number} The index of the instance inside the series or -1 if not found.
*/
_proto.indexOfInstance = function () {
function indexOfInstance(instance) {
return this._instances.indexOf(instance);
}
return indexOfInstance;
}();
/**
* Search the associated instances using the supplied callback as criteria. The callback is passed
* two arguments: instance (a InstanceMetadata instance) and index (the integer
* index of the instance within its series)
* @param {function} callback The callback function which will be invoked for each instance.
* @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it
* returns a InstanceMetadata. "undefined" is returned otherwise
*/
_proto.findInstance = function () {
function findInstance(callback) {
if (Metadata.isValidCallback(callback)) {
return this._instances.find(function (instance, index) {
return callback.call(null, instance, index);
});
}
}
return findInstance;
}();
/**
* Compares the current series with another one.
* @param {SeriesMetadata} series An instance of the SeriesMetadata class.
* @returns {boolean} Returns true if both instances refer to the same series.
*/
_proto.equals = function () {
function equals(series) {
var self = this;
return series === self || series instanceof SeriesMetadata && series.getSeriesInstanceUID() === self.getSeriesInstanceUID();
}
return equals;
}();
return SeriesMetadata;
}(Metadata);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"StudyMetadata.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/metadata/StudyMetadata.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
module.export({
StudyMetadata: function () {
return StudyMetadata;
}
});
var Metadata;
module.watch(require("./Metadata"), {
Metadata: function (v) {
Metadata = v;
}
}, 0);
var SeriesMetadata;
module.watch(require("./SeriesMetadata"), {
SeriesMetadata: function (v) {
SeriesMetadata = v;
}
}, 1);
var InstanceMetadata;
module.watch(require("./InstanceMetadata"), {
InstanceMetadata: function (v) {
InstanceMetadata = v;
}
}, 2);
var ImageSet;
module.watch(require("../ImageSet"), {
ImageSet: function (v) {
ImageSet = v;
}
}, 3);
var OHIFError;
module.watch(require("../OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 4);
var StudyMetadata =
/*#__PURE__*/
function (_Metadata) {
(0, _inheritsLoose2.default)(StudyMetadata, _Metadata);
function StudyMetadata(data, uid) {
var _this;
_this = _Metadata.call(this, data, uid) || this; // Initialize Private Properties
Object.defineProperties((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), {
_studyInstanceUID: {
configurable: true,
// configurable so that it can be redefined in sub-classes...
enumerable: false,
writable: true,
value: null
},
_series: {
configurable: false,
enumerable: false,
writable: false,
value: []
},
_displaySets: {
configurable: false,
enumerable: false,
writable: false,
value: []
},
_firstSeries: {
configurable: false,
enumerable: false,
writable: true,
value: null
},
_firstInstance: {
configurable: false,
enumerable: false,
writable: true,
value: null
}
}); // Initialize Public Properties
_this._definePublicProperties();
return _this;
}
/**
* Private Methods
*/
/**
* Define Public Properties
* This method should only be called during initialization (inside the class constructor)
*/
var _proto = StudyMetadata.prototype;
_proto._definePublicProperties = function () {
function _definePublicProperties() {
/**
* Property: this.studyInstanceUID
* Same as this.getStudyInstanceUID()
* It's specially useful in contexts where a method call is not suitable like in search criteria. For example:
* studyCollection.findBy({
* studyInstanceUID: '1.2.3.4.5.6.77777.8888888.99999999999.0'
* });
*/
Object.defineProperty(this, 'studyInstanceUID', {
configurable: false,
enumerable: false,
get: function () {
return this.getStudyInstanceUID();
}
});
}
return _definePublicProperties;
}();
/**
* Public Methods
*/
/**
* Getter for displaySets
* @return {Array} Array of display set object
*/
_proto.getDisplaySets = function () {
function getDisplaySets() {
return this._displaySets.slice();
}
return getDisplaySets;
}();
/**
* Set display sets
* @param {Array} displaySets Array of display sets (ImageSet[])
*/
_proto.setDisplaySets = function () {
function setDisplaySets(displaySets) {
var _this2 = this;
displaySets.forEach(function (displaySet) {
return _this2.addDisplaySet(displaySet);
});
}
return setDisplaySets;
}();
/**
* Add a single display set to the list
* @param {Object} displaySet Display set object
* @returns {boolean} True on success, false on failure.
*/
_proto.addDisplaySet = function () {
function addDisplaySet(displaySet) {
if (displaySet instanceof ImageSet) {
this._displaySets.push(displaySet);
return true;
}
return false;
}
return addDisplaySet;
}();
/**
* Invokes the supplied callback for each display set in the current study passing
* two arguments: display set (a ImageSet instance) and index (the integer
* index of the display set within the current study)
* @param {function} callback The callback function which will be invoked for each display set instance.
* @returns {undefined} Nothing is returned.
*/
_proto.forEachDisplaySet = function () {
function forEachDisplaySet(callback) {
if (Metadata.isValidCallback(callback)) {
this._displaySets.forEach(function (displaySet, index) {
callback.call(null, displaySet, index);
});
}
}
return forEachDisplaySet;
}();
/**
* Search the associated display sets using the supplied callback as criteria. The callback is passed
* two arguments: display set (a ImageSet instance) and index (the integer
* index of the display set within the current study)
* @param {function} callback The callback function which will be invoked for each display set instance.
* @returns {undefined} Nothing is returned.
*/
_proto.findDisplaySet = function () {
function findDisplaySet(callback) {
if (Metadata.isValidCallback(callback)) {
return this._displaySets.find(function (displaySet, index) {
return callback.call(null, displaySet, index);
});
}
}
return findDisplaySet;
}();
/**
* Retrieve the number of display sets within the current study.
* @returns {number} The number of display sets in the current study.
*/
_proto.getDisplaySetCount = function () {
function getDisplaySetCount() {
return this._displaySets.length;
}
return getDisplaySetCount;
}();
/**
* Returns the StudyInstanceUID of the current study.
*/
_proto.getStudyInstanceUID = function () {
function getStudyInstanceUID() {
return this._studyInstanceUID;
}
return getStudyInstanceUID;
}();
/**
* Getter for series
* @return {Array} Array of SeriesMetadata object
*/
_proto.getSeries = function () {
function getSeries() {
return this._series.slice();
}
return getSeries;
}();
/**
* Append a series to the current study.
* @param {SeriesMetadata} series The series to be added to the current study.
* @returns {boolean} Returns true on success, false otherwise.
*/
_proto.addSeries = function () {
function addSeries(series) {
var result = false;
if (series instanceof SeriesMetadata && this.getSeriesByUID(series.getSeriesInstanceUID()) === void 0) {
this._series.push(series);
result = true;
}
return result;
}
return addSeries;
}();
/**
* Find a series by index.
* @param {number} index An integer representing a list index.
* @returns {SeriesMetadata} Returns a SeriesMetadata instance when found or undefined otherwise.
*/
_proto.getSeriesByIndex = function () {
function getSeriesByIndex(index) {
var found; // undefined by default...
if (Metadata.isValidIndex(index)) {
found = this._series[index];
}
return found;
}
return getSeriesByIndex;
}();
/**
* Find a series by SeriesInstanceUID.
* @param {string} uid An UID string.
* @returns {SeriesMetadata} Returns a SeriesMetadata instance when found or undefined otherwise.
*/
_proto.getSeriesByUID = function () {
function getSeriesByUID(uid) {
var found; // undefined by default...
if (Metadata.isValidUID(uid)) {
found = this._series.find(function (series) {
return series.getSeriesInstanceUID() === uid;
});
}
return found;
}
return getSeriesByUID;
}();
/**
* Retrieve the number of series within the current study.
* @returns {number} The number of series in the current study.
*/
_proto.getSeriesCount = function () {
function getSeriesCount() {
return this._series.length;
}
return getSeriesCount;
}();
/**
* Retrieve the number of instances within the current study.
* @returns {number} The number of instances in the current study.
*/
_proto.getInstanceCount = function () {
function getInstanceCount() {
return this._series.reduce(function (sum, series) {
return sum + series.getInstanceCount();
}, 0);
}
return getInstanceCount;
}();
/**
* Invokes the supplied callback for each series in the current study passing
* two arguments: series (a SeriesMetadata instance) and index (the integer
* index of the series within the current study)
* @param {function} callback The callback function which will be invoked for each series instance.
* @returns {undefined} Nothing is returned.
*/
_proto.forEachSeries = function () {
function forEachSeries(callback) {
if (Metadata.isValidCallback(callback)) {
this._series.forEach(function (series, index) {
callback.call(null, series, index);
});
}
}
return forEachSeries;
}();
/**
* Find the index of a series inside the study.
* @param {SeriesMetadata} series An instance of the SeriesMetadata class.
* @returns {number} The index of the series inside the study or -1 if not found.
*/
_proto.indexOfSeries = function () {
function indexOfSeries(series) {
return this._series.indexOf(series);
}
return indexOfSeries;
}();
/**
* It sorts the series based on display sets order. Each series must be an instance
* of SeriesMetadata and each display sets must be an instance of ImageSet.
* Useful example of usage:
* Study data provided by backend does not sort series at all and client-side
* needs series sorted by the same criteria used for sorting display sets.
*/
_proto.sortSeriesByDisplaySets = function () {
function sortSeriesByDisplaySets() {
var _this3 = this;
// Object for mapping display sets' index by seriesInstanceUid
var displaySetsMapping = {}; // Loop through each display set to create the mapping
this.forEachDisplaySet(function (displaySet, index) {
if (!(displaySet instanceof ImageSet)) {
throw new OHIFError("StudyMetadata::sortSeriesByDisplaySets display set at index " + index + " is not an instance of ImageSet");
} // In case of multiframe studies, just get the first index occurence
if (displaySetsMapping[displaySet.seriesInstanceUid] === void 0) {
displaySetsMapping[displaySet.seriesInstanceUid] = index;
}
}); // Clone of actual series
var actualSeries = this.getSeries();
actualSeries.forEach(function (series, index) {
if (!(series instanceof SeriesMetadata)) {
throw new OHIFError("StudyMetadata::sortSeriesByDisplaySets series at index " + index + " is not an instance of SeriesMetadata");
} // Get the new series index
var seriesIndex = displaySetsMapping[series.getSeriesInstanceUID()]; // Update the series object with the new series position
_this3._series[seriesIndex] = series;
});
}
return sortSeriesByDisplaySets;
}();
/**
* Compares the current study instance with another one.
* @param {StudyMetadata} study An instance of the StudyMetadata class.
* @returns {boolean} Returns true if both instances refer to the same study.
*/
_proto.equals = function () {
function equals(study) {
var self = this;
return study === self || study instanceof StudyMetadata && study.getStudyInstanceUID() === self.getStudyInstanceUID();
}
return equals;
}();
/**
* Get the first series of the current study retaining a consistent result across multiple calls.
* @return {SeriesMetadata} An instance of the SeriesMetadata class or null if it does not exist.
*/
_proto.getFirstSeries = function () {
function getFirstSeries() {
var series = this._firstSeries;
if (!(series instanceof SeriesMetadata)) {
series = null;
var found = this.getSeriesByIndex(0);
if (found instanceof SeriesMetadata) {
this._firstSeries = found;
series = found;
}
}
return series;
}
return getFirstSeries;
}();
/**
* Get the first instance of the current study retaining a consistent result across multiple calls.
* @return {InstanceMetadata} An instance of the InstanceMetadata class or null if it does not exist.
*/
_proto.getFirstInstance = function () {
function getFirstInstance() {
var instance = this._firstInstance;
if (!(instance instanceof InstanceMetadata)) {
instance = null;
var firstSeries = this.getFirstSeries();
if (firstSeries instanceof SeriesMetadata) {
var found = firstSeries.getFirstInstance();
if (found instanceof InstanceMetadata) {
this._firstInstance = found;
instance = found;
}
}
}
return instance;
}
return getFirstInstance;
}();
/**
* Search the associated series to find an specific instance using the supplied callback as criteria.
* The callback is passed two arguments: instance (a InstanceMetadata instance) and index (the integer
* index of the instance within the current series)
* @param {function} callback The callback function which will be invoked for each instance instance.
* @returns {Object} Result object containing series (SeriesMetadata) and instance (InstanceMetadata)
* objects or an empty object if not found.
*/
_proto.findSeriesAndInstanceByInstance = function () {
function findSeriesAndInstanceByInstance(callback) {
var result;
if (Metadata.isValidCallback(callback)) {
var instance;
var series = this._series.find(function (series) {
instance = series.findInstance(callback);
return instance instanceof InstanceMetadata;
}); // No series found
if (series instanceof SeriesMetadata) {
result = {
series: series,
instance: instance
};
}
}
return result || {};
}
return findSeriesAndInstanceByInstance;
}();
/**
* Find series by instance using the supplied callback as criteria. The callback is passed
* two arguments: instance (a InstanceMetadata instance) and index (the integer index of
* the instance within its series)
* @param {function} callback The callback function which will be invoked for each instance.
* @returns {SeriesMetadata|undefined} If a series is found based on callback criteria it
* returns a SeriesMetadata. "undefined" is returned otherwise
*/
_proto.findSeriesByInstance = function () {
function findSeriesByInstance(callback) {
var result = this.findSeriesAndInstanceByInstance(callback);
return result.series;
}
return findSeriesByInstance;
}();
/**
* Find an instance using the supplied callback as criteria. The callback is passed
* two arguments: instance (a InstanceMetadata instance) and index (the integer index of
* the instance within its series)
* @param {function} callback The callback function which will be invoked for each instance.
* @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it
* returns a InstanceMetadata. "undefined" is returned otherwise
*/
_proto.findInstance = function () {
function findInstance(callback) {
var result = this.findSeriesAndInstanceByInstance(callback);
return result.instance;
}
return findInstance;
}();
return StudyMetadata;
}(Metadata);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"StudySummary.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/metadata/StudySummary.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
module.export({
StudySummary: function () {
return StudySummary;
}
});
var Metadata;
module.watch(require("./Metadata"), {
Metadata: function (v) {
Metadata = v;
}
}, 0);
var OHIFError;
module.watch(require("../OHIFError"), {
OHIFError: function (v) {
OHIFError = v;
}
}, 1);
var DICOMTagDescriptions;
module.watch(require("../../DICOMTagDescriptions"), {
DICOMTagDescriptions: function (v) {
DICOMTagDescriptions = v;
}
}, 2);
/**
* Constants
*/
var STUDY_INSTANCE_UID = 'x0020000d';
/**
* Class Definition
*/
var StudySummary =
/*#__PURE__*/
function (_Metadata) {
(0, _inheritsLoose2.default)(StudySummary, _Metadata);
function StudySummary(tagMap, attributeMap, uid) {
var _this;
// Call the superclass constructor passing an plain object with no prototype to be used as the main "_data" attribute.
var _data = Object.create(null);
_this = _Metadata.call(this, _data, uid) || this; // Initialize internal tag map if first argument is given.
if (tagMap !== void 0) {
_this.addTags(tagMap);
} // Initialize internal property map if second argument is given.
if (attributeMap !== void 0) {
_this.setCustomAttributes(attributeMap);
}
return _this;
}
var _proto = StudySummary.prototype;
_proto.getStudyInstanceUID = function () {
function getStudyInstanceUID() {
// This method should return null if StudyInstanceUID is not available to keep compatibility StudyMetadata API
return this.getTagValue(STUDY_INSTANCE_UID) || null;
}
return getStudyInstanceUID;
}();
/**
* Append tags to internal tag map.
* @param {Object} tagMap An object whose own properties will be used as tag values and appended to internal tag map.
*/
_proto.addTags = function () {
function addTags(tagMap) {
var _hasOwn = Object.prototype.hasOwnProperty;
var _data = this._data;
for (var tag in meteorBabelHelpers.sanitizeForInObject(tagMap)) {
if (_hasOwn.call(tagMap, tag)) {
var description = DICOMTagDescriptions.find(tag); // When a description is available, use its tag as internal key...
if (description) {
_data[description.tag] = tagMap[tag];
} else {
_data[tag] = tagMap[tag];
}
}
}
}
return addTags;
}();
_proto.tagExists = function () {
function tagExists(tagName) {
var _data = this._data;
var description = DICOMTagDescriptions.find(tagName);
if (description) {
return description.tag in _data;
}
return tagName in _data;
}
return tagExists;
}();
_proto.getTagValue = function () {
function getTagValue(tagName) {
var _data = this._data;
var description = DICOMTagDescriptions.find(tagName);
if (description) {
return _data[description.tag];
}
return _data[tagName];
}
return getTagValue;
}();
return StudySummary;
}(Metadata);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"WadoRsMetaDataBuilder.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/metadata/WadoRsMetaDataBuilder.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
WadoRsMetaDataBuilder: function () {
return WadoRsMetaDataBuilder;
}
});
var WadoRsMetaDataBuilder =
/*#__PURE__*/
function () {
function WadoRsMetaDataBuilder() {
this.tags = {};
}
var _proto = WadoRsMetaDataBuilder.prototype;
_proto.addTag = function () {
function addTag(tag, value, multi) {
this.tags[tag] = {
tag: tag,
value: value,
multi: multi
};
return this;
}
return addTag;
}();
_proto.toJSON = function () {
function toJSON() {
var _this = this;
var json = {};
var keys = Object.keys(this.tags);
keys.forEach(function (key) {
if (!_this.tags.hasOwnProperty(key)) {
return;
}
var tag = _this.tags[key];
var multi = !!tag.multi;
var value = tag.value;
if (value == null || value.length === 1 && value[0] == null) {
return;
}
if (typeof value === 'string' && multi) {
value = value.split('\\');
}
if (!_.isArray(value)) {
value = [value];
}
json[key] = {
Value: value
};
});
return json;
}
return toJSON;
}();
return WadoRsMetaDataBuilder;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}},"plugins":{"OHIFPlugin.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/plugins/OHIFPlugin.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var module1 = module;
module1.export({
OHIFPlugin: function () {
return OHIFPlugin;
}
});
var OHIFPlugin =
/*#__PURE__*/
function () {
// TODO: this class is still under development and will
// likely change in the near future
function OHIFPlugin() {
this.name = "Unnamed plugin";
this.description = "No description available";
} // load an individual script URL
OHIFPlugin.loadScript = function () {
function loadScript(scriptURL) {
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "text/javascript";
return new Promise(function (resolve, reject) {
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.onload = function () {
head.removeChild(script);
resolve();
};
script.onerror = reject;
script.src = scriptURL;
script.type = type;
script.async = false;
head.appendChild(script);
});
}
return loadScript;
}(); // reload all the dependency scripts and also
// the main plugin script url.
OHIFPlugin.reloadPlugin = function () {
function reloadPlugin(plugin) {
var _this = this;
if (plugin.scriptURLs && plugin.scriptURLs.length) {
plugin.scriptURLs.forEach(function (scriptURL) {
_this.loadScript(scriptURL);
});
} // TODO: Later we should probably merge script and module URLs
if (plugin.moduleURLs && plugin.moduleURLs.length) {
plugin.moduleURLs.forEach(function (moduleURLs) {
_this.loadScript(moduleURLs, "module");
});
}
var scriptURL = plugin.url;
if (plugin.allowCaching === false) {
scriptURL += "?" + performance.now();
}
var type = plugin.module === true ? 'module' : 'text/javascript';
console.warn("Calling loadScript for " + plugin.name);
console.time("loadScript " + plugin.name);
this.loadScript(scriptURL, type).then(function (script) {
console.timeEnd("loadScript " + plugin.name);
var entryPointFunction = OHIF.plugins.entryPoints[plugin.name];
if (entryPointFunction) {
entryPointFunction();
} else {
throw new Error("No entry point found for " + plugin.name);
}
}, function (error) {
throw new Error(error);
});
}
return reloadPlugin;
}();
return OHIFPlugin;
}();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"ViewportPlugin.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/plugins/ViewportPlugin.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
module.export({
ViewportPlugin: function () {
return ViewportPlugin;
}
});
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 0);
var Tracker;
module.watch(require("meteor/tracker"), {
Tracker: function (v) {
Tracker = v;
}
}, 1);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 2);
var OHIFPlugin;
module.watch(require("./OHIFPlugin"), {
OHIFPlugin: function (v) {
OHIFPlugin = v;
}
}, 3);
var ViewportPlugin =
/*#__PURE__*/
function (_OHIFPlugin) {
(0, _inheritsLoose2.default)(ViewportPlugin, _OHIFPlugin);
function ViewportPlugin(name) {
var _this;
_this = _OHIFPlugin.call(this) || this;
_this.name = name;
_this._destroyed = false;
_this._setupListeners();
return _this;
}
/**
* Retrieve a Display Set for a specific viewport by viewport index,
* if one is already displayed in the viewport.
*
* @static
* @param {Number} viewportIndex
* @return {undefined|ImageSet}
*/
ViewportPlugin.getDisplaySet = function () {
function getDisplaySet(viewportIndex) {
// TODO: Move layoutManager from viewerbase to viewer
var layoutManager = OHIF.viewerbase.layoutManager;
var viewportData = layoutManager.viewportData[viewportIndex];
var studyInstanceUid = viewportData.studyInstanceUid,
displaySetInstanceUid = viewportData.displaySetInstanceUid;
var studyMetadata = OHIF.viewer.StudyMetadataList.findBy({
studyInstanceUID: studyInstanceUid
});
return studyMetadata.findDisplaySet(function (displaySet) {
return displaySet.displaySetInstanceUid === displaySetInstanceUid;
});
}
return getDisplaySet;
}();
/**
* Set up the viewport using the plugin.
*
* This should be implemented by the child class.
*
* @abstract
*
* @param {HTMLElement} div
* @param {ImageSet} displaySet
* @param {Object} viewportDetails
*/
var _proto = ViewportPlugin.prototype;
_proto.setupViewport = function () {
function setupViewport(div, displaySet, viewportDetails) {
throw new Error('You must override this method!');
}
return setupViewport;
}();
/**
* Switch a single viewport to use the current ViewportPlugin
*
* @param {Number} viewportIndex The viewport to switch to the current plugin type
*/
_proto.setViewportToPlugin = function () {
function setViewportToPlugin(viewportIndex) {
if (!this.name) {
throw new Error('ViewportPlugin subclasses must have a name');
}
var layoutManager = OHIF.viewerbase.layoutManager;
var viewportData = layoutManager.viewportData[viewportIndex];
if (viewportData.plugin === this.name) {
OHIF.log.info("setViewportToPlugin: Viewport " + viewportIndex + " already set to plugin " + this.name);
}
viewportData.plugin = this.name;
layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, viewportData);
}
return setViewportToPlugin;
}();
/**
* Runs 'setupViewport' for the ViewportPlugin on all viewports which should
* be rendered by this plugin, but have not yet been initialized. Viewports
* which already contain contents are skipped.
*
* @private
*/
_proto._initEmptyPluginViewports = function () {
function _initEmptyPluginViewports() {
var _this2 = this;
if (!this.name) {
throw new Error('ViewportPlugin subclasses must have a name');
} // Find all Viewport HTMLElements currently using this plugin
var pluginDivs = Array.from(document.querySelectorAll(".viewport-plugin-" + this.name)); // If there are no Viewports using this plugin, stop here
if (!pluginDivs.length) {
return;
}
var emptyPluginDivs = pluginDivs.filter(function (div) {
// Keep only divs owned by the plugin which have no contents
return div.innerHTML.trim() === '';
});
OHIF.log.info(this.name + ": Initializing " + emptyPluginDivs.length + " viewports"); // Retrieve the list of all viewports, so we can figure out the viewport details
var allViewports = Array.from(document.querySelectorAll('.viewportContainer'));
var layoutManager = OHIF.viewerbase.layoutManager;
emptyPluginDivs.forEach(function (div) {
// Identify the Viewport index, and any display set that is currently
// hung in the viewport
var viewportIndex = allViewports.indexOf(div.parentNode);
var viewportData = layoutManager.viewportData[viewportIndex];
var displaySet = ViewportPlugin.getDisplaySet(viewportIndex); // Use the plugin's setupViewport function to render the contents
// of this viewport.
_this2.setupViewport(div, viewportData, displaySet);
});
}
return _initEmptyPluginViewports;
}();
/**
* Listen for changes to the viewport layout which would necessitate a
* rerendering of the viewports. When this happens, re-render all viewports
* which are using this plugin.
*
* @private
*/
_proto._setupListeners = function () {
function _setupListeners() {
var _this3 = this;
if (!this.name) {
throw new Error('ViewportPlugin subclasses must have a name');
}
console.warn("_setupListeners: " + this.name); // TODO: Stop using Meteor's reactivity here
Tracker.autorun(function (computation) {
var random = Session.get('LayoutManagerUpdated');
console.warn("LayoutManagerUpdated: " + _this3.name + ": " + random); // Bail out if this is the first time the autorun
// executes (i.e. when it is being defined).
//
// Note: This has to be checked after the dependency on the
// Session variable above, or the reactive dependency will not
// be established.
if (computation.firstRun === true) {
return;
} // In case we need to disable the use
// of this plugin, we can also stop the
// reactive computation by setting
// this.destroyed to true.
if (_this3._destroyed === true) {
computation.stop();
} // Identify all viewports which should be
// rendered by the ViewportPlugin, and render
// them.
_this3._initEmptyPluginViewports();
});
}
return _setupListeners;
}();
/**
* Stop listening for changes to the viewport layout in order to
* automatically rerender viewports setup for use by this plugin.
*/
_proto.stopListeners = function () {
function stopListeners() {
this._destroyed = true;
}
return stopListeners;
}();
return ViewportPlugin;
}(OHIFPlugin);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"index.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/classes/plugins/index.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
var OHIFPlugin;
module.watch(require("./OHIFPlugin"), {
OHIFPlugin: function (v) {
OHIFPlugin = v;
}
}, 1);
var ViewportPlugin;
module.watch(require("./ViewportPlugin"), {
ViewportPlugin: function (v) {
ViewportPlugin = v;
}
}, 2);
// Each plugin registers an entry point function to be called
// when the loading is complete.
var plugins = {
OHIFPlugin: OHIFPlugin,
ViewportPlugin: ViewportPlugin,
entryPoints: {}
}; // TODO: When we reorganize the packages, we should figure out where to put this.
OHIF.plugins = plugins;
module.exportDefault(plugins);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}}},"helpers":{"capitalizeFirstLetter.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/capitalizeFirstLetter.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
/**
* A global Blaze UI helper to capitalizes the first letter of an input String
*
* Credit to:
*
* http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript
*/
Blaze.registerHelper('capitalizeFirstLetter', function (context) {
if (!context) {
return;
}
return context.charAt(0).toUpperCase() + context.slice(1);
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"formatDA.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/formatDA.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
formatDA: function () {
return formatDA;
}
});
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
var moment;
module.watch(require("meteor/momentjs:moment"), {
moment: function (v) {
moment = v;
}
}, 1);
/**
* A global Blaze UI helper function to format DICOM Dates using the Moment library
*/
var formatDA = function (context, format, options) {
if (!context) {
return undefined;
}
var dateAsMoment = moment(context, "YYYYMMDD");
var strFormat = "MMM D, YYYY";
if (options) {
strFormat = format;
}
return dateAsMoment.format(strFormat);
}; // Check if global helper already exists to not override it
if (!Blaze._getGlobalHelper('formatDA')) {
Blaze.registerHelper('formatDA', formatDA);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"formatJSDate.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/formatJSDate.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
var moment;
module.watch(require("meteor/momentjs:moment"), {
moment: function (v) {
moment = v;
}
}, 1);
/**
* A global Blaze UI helper function to format JavaScript Dates using the Moment library
*/
Blaze.registerHelper('formatJSDate', function (context, format, options) {
if (!context) {
return;
}
var dateAsMoment = moment(new Date(context));
var strFormat = 'MMM D, YYYY';
if (options) {
strFormat = format;
}
return dateAsMoment.format(strFormat);
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"formatNumberPrecision.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/formatNumberPrecision.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
/**
* A global Blaze UI helper to format a float value to a specified precision
*/
Blaze.registerHelper('formatNumberPrecision', function (context, precision) {
if (context != null) {
return parseFloat(context).toFixed(precision);
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"formatPN.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/formatPN.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
formatPN: function () {
return formatPN;
}
});
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
/**
* Formats a patient name for display purposes
*/
var formatPN = function (context) {
if (!context) {
return;
} // Convert the first ^ to a ', '. String.replace() only affects
// the first appearance of the character.
var commaBetweenFirstAndLast = context.replace('^', ', '); // Replace any remaining '^' characters with spaces
var cleaned = commaBetweenFirstAndLast.replace(/\^/g, ' '); // Trim any extraneous whitespace
return cleaned.trim();
};
/**
* A global Blaze UI helper to format a patient name for display purposes
*/
// Check if global helper already exists to not override it
if (!Blaze._getGlobalHelper('formatPN')) {
Blaze.registerHelper('formatPN', formatPN);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"formatTM.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/formatTM.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
formatTM: function () {
return formatTM;
}
});
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
var moment;
module.watch(require("meteor/momentjs:moment"), {
moment: function (v) {
moment = v;
}
}, 1);
/**
* A global Blaze UI helper to format a DICOM Time for display using the Moment library
*/
var formatTM = function (context, options) {
if (!context) {
return;
} // DICOM Time is stored as HHmmss.SSS, where:
// HH 24 hour time:
// m mm 0..59 Minutes
// s ss 0..59 Seconds
// S SS SSS 0..999 Fractional seconds
//
// See MomentJS: http://momentjs.com/docs/#/parsing/string-format/
var dateTime = moment(context, 'HHmmss.SSS');
var format = "HH:mm:ss";
if (options && options.format) {
format = options.format;
}
return dateTime.format(format);
}; // Check if global helper already exists to not override it
if (!Blaze._getGlobalHelper('formatTM')) {
Blaze.registerHelper('formatTM', formatTM);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"getUsername.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/getUsername.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Meteor;
module.watch(require("meteor/meteor"), {
Meteor: function (v) {
Meteor = v;
}
}, 0);
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 1);
/**
* Helper for retrieving username given userId
*/
Blaze.registerHelper('getUsername', function (userId) {
var user = Meteor.users.findOne({
userId: userId
});
if (user && user.name) {
return user.name;
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"ifTypeIs.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/ifTypeIs.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
/**
* Helper for checking datatype of a variable
*/
Blaze.registerHelper('ifTypeIs', function (value, match, attributeName) {
if ((0, _typeof2.default)(value) === match) {
return attributeName;
}
return '';
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"inc.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/inc.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
Blaze.registerHelper('inc', function (value) {
return parseInt(value) + 1;
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"index.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/index.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
helpers: function () {
return helpers;
}
});
var isTouchDevice;
module.watch(require("./isTouchDevice"), {
isTouchDevice: function (v) {
isTouchDevice = v;
}
}, 0);
var formatPN;
module.watch(require("./formatPN"), {
formatPN: function (v) {
formatPN = v;
}
}, 1);
var formatDA;
module.watch(require("./formatDA"), {
formatDA: function (v) {
formatDA = v;
}
}, 2);
var formatTM;
module.watch(require("./formatTM"), {
formatTM: function (v) {
formatTM = v;
}
}, 3);
module.watch(require("./formatJSDate"));
module.watch(require("./jsDateFromNow"));
module.watch(require("./formatNumberPrecision"));
module.watch(require("./inc"));
module.watch(require("./isDisplaySetActive"));
module.watch(require("./getUsername"));
module.watch(require("./capitalizeFirstLetter"));
module.watch(require("./objectToPairs"));
module.watch(require("./objectEach"));
module.watch(require("./ifTypeIs"));
module.watch(require("./prettyPrintStringify"));
module.watch(require("./sorting"));
module.watch(require("./studyThumbnails"));
/**
* Exposed interface...
*/
var helpers = {
isTouchDevice: isTouchDevice,
formatPN: formatPN,
formatDA: formatDA,
formatTM: formatTM
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"isDisplaySetActive.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/isDisplaySetActive.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 1);
var $;
module.watch(require("meteor/jquery"), {
$: function (v) {
$ = v;
}
}, 2);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 3);
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 4);
module.watch(require("meteor/ohif:viewerbase"));
/**
* Boolean helper to identify if a series instance is active in some viewport
*/
Template.registerHelper('isDisplaySetActive', function (displaySetInstanceUid, viewportIndex) {
// Run this computation every time the viewports are updated
Session.get('LayoutManagerUpdated'); // Stop here if layoutManager is not defined yet
if (!OHIF.viewerbase.layoutManager) {
return;
} // Check if the display set is current visible in any of the layout
// manager's displayed viewports. Note that we have to check the
// onscreen number of viewports here, since the layout manager will
// keep the viewport data of old viewports, even after the layout is changed.
//
// This behaviour is intentional. If the user displays four viewports, then assigns
// display sets to them, and then switches to / from another layout configuration,
// we don't want them to lose their specified viewports.
var result = false;
if (_.isUndefined(viewportIndex)) {
// Get the number of viewports that are currently displayed
// (Note, viewportData may have more entries!)
var currentNumberOfViewports = OHIF.viewerbase.layoutManager.getNumberOfViewports(); // Loop through the viewport data up until the currently displayed
// number of viewports
var viewportData = OHIF.viewerbase.layoutManager.viewportData;
for (var i = 0; i < currentNumberOfViewports; i++) {
var data = viewportData[i]; // If the display set is displayed in this viewport and is active, stop here
if (data && data.displaySetInstanceUid === displaySetInstanceUid) {
result = true;
break;
}
}
} else {
var _data = OHIF.viewerbase.layoutManager.viewportData[viewportIndex]; // If the display set is displayed in this viewport, stop here
if (_data && _data.displaySetInstanceUid === displaySetInstanceUid) {
result = true;
}
}
return result;
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"isTouchDevice.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/isTouchDevice.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
isTouchDevice: function () {
return isTouchDevice;
}
});
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
/**
* Helper function to determine if the current client devices
* is touch-capable. This can be used to modify certain aspects of the UI.
*
* The check may not work on all devices!
*
* @returns {boolean} true if the client device is touch-capable, false otherwise
*/
var isTouchDevice = function () {
return 'ontouchstart' in window || navigator.MaxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
};
/**
* Blaze helper for checking if the current device is touch capable
*
* @returns {boolean} true if the client device is touch-capable, false otherwise
*/
Blaze.registerHelper('isTouchDevice', isTouchDevice);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"jsDateFromNow.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/jsDateFromNow.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
var Session;
module.watch(require("meteor/session"), {
Session: function (v) {
Session = v;
}
}, 1);
var moment;
module.watch(require("meteor/momentjs:moment"), {
moment: function (v) {
moment = v;
}
}, 2);
/**
* A global Blaze UI helper function to format JavaScript Dates using the Moment library
*/
Blaze.registerHelper('jsDateFromNow', function (context, format, options) {
if (!context) {
return;
}
Session.get('timeAgoVariable');
var dateAsMoment = moment(new Date(context));
return dateAsMoment.fromNow();
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"objectEach.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/objectEach.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 1);
Blaze.registerHelper('objectEach', function (object) {
// http://stackoverflow.com/questions/30234732/how-to-print-key-and-values-in-meteor-template
return _.map(object, function (value, key) {
return _.extend({
key: key
}, value);
});
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"objectToPairs.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/objectToPairs.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 1);
Blaze.registerHelper('objectToPairs', function (object) {
// http://stackoverflow.com/questions/30234732/how-to-print-key-and-values-in-meteor-template
return _.map(object, function (value, key) {
return {
key: key,
value: value
};
});
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"prettyPrintStringify.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/prettyPrintStringify.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Blaze;
module.watch(require("meteor/blaze"), {
Blaze: function (v) {
Blaze = v;
}
}, 0);
/**
* A global Blaze UI helper to Stringify a JavaScript object
*
* Credit to:
*
* http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript
*/
Blaze.registerHelper('prettyPrintStringify', function (context) {
if (!context) {
return;
}
var string = JSON.stringify(context, null, 2);
string = string.replace(/['"]+/g, '');
string = string.replace('{', '');
string = string.replace('}', '');
string = string.replace(',', '\n');
return string;
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"sorting.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/sorting.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 1);
/**
* Global Blaze UI helper to sort array elements
* by an array element's property (property) or deep object property (property.childProperty)
* Sorts ascending as default
*/
Template.registerHelper('sort', function (array, sortBy, sortType) {
if (!sortBy) {
return array;
} // To keep the order for the same values of the field which is used to sort:
// 1. Group the array by the field
// 2. Sort the grouped array
// 3. Ungroup the sorted array
var groupedArray = _.groupBy(array, function (element) {
if (sortBy) {
var groupingElement = getKeyValue(element, sortBy);
if (groupingElement) {
return groupingElement;
}
}
return element;
});
var sortedArray = _.sortBy(groupedArray, function (element) {
if (sortBy) {
var sortingElement = getKeyValue(element[0], sortBy);
if (sortingElement) {
return sortingElement;
}
}
return element;
});
if (sortType === 'desc') {
return _.flatten(sortedArray.reverse(), true);
}
return _.flatten(sortedArray, true);
});
function getKeyValue(object, keyPath) {
keyPath = keyPath.split('.');
for (var i = 0; i < keyPath.length; i++) {
if (object && _.has(object, keyPath[i])) {
object = object[keyPath[i]];
} else {
return undefined;
}
}
return object;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"studyThumbnails.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/lib/helpers/studyThumbnails.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var Template;
module.watch(require("meteor/templating"), {
Template: function (v) {
Template = v;
}
}, 0);
var _;
module.watch(require("meteor/underscore"), {
_: function (v) {
_ = v;
}
}, 1);
/**
* A global Blaze UI helper to get the thumbnails for the given study
*/
Template.registerHelper('studyThumbnails', function (study) {
if (!study) {
return;
} // Find the study's stacks
var stacks = study.displaySets; // Defines the resulting thumbnails list
var thumbnails = []; // Iterate over the stacks and add one by one with its index
_.each(stacks, function (stack, thumbnailIndex) {
thumbnails.push({
thumbnailIndex: thumbnailIndex,
stack: stack
});
});
return thumbnails;
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}}}},"main.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/main.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var module1 = module;
module1.export({
OHIF: function () {
return OHIF;
},
Viewerbase: function () {
return Viewerbase;
}
});
var OHIF, Viewerbase;
module1.watch(require("./namespace.js"), {
OHIF: function (v) {
OHIF = v;
},
Viewerbase: function (v) {
Viewerbase = v;
}
}, 0);
module1.watch(require("./client/"));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
},"namespace.js":function(require,exports,module){
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/namespace.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
module.export({
OHIF: function () {
return OHIF;
},
Viewerbase: function () {
return Viewerbase;
}
});
var OHIF;
module.watch(require("meteor/ohif:core"), {
OHIF: function (v) {
OHIF = v;
}
}, 0);
/**
* Create Viewerbase namespace
*/
var Viewerbase = {};
/**
* Append Viewerbase namespace to OHIF namespace
*/
OHIF.viewerbase = Viewerbase;
/**
* Export relevant objects
*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}}}}},{
"extensions": [
".js",
".json",
".styl",
".html"
]
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/ohif_viewerbase/client/compatibility/dialogPolyfill.js //
// This file is in bare mode and is not in its own closure. //
// //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
var dialogPolyfill = (function() {
var supportCustomEvent = window.CustomEvent;
if (!supportCustomEvent || typeof supportCustomEvent == "object") {
supportCustomEvent = function CustomEvent(event, x) {
x = x || {};
var ev = document.createEvent('CustomEvent');
ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null);
return ev;
};
supportCustomEvent.prototype = window.Event.prototype;
}
/**
* Finds the nearest <dialog> from the passed element.
*
* @param {Element} el to search from
* @param {HTMLDialogElement} dialog found
*/
function findNearestDialog(el) {
while (el) {
if (el.nodeName == 'DIALOG') {
return el;
}
el = el.parentElement;
}
return null;
}
var dialogPolyfill = {};
dialogPolyfill.reposition = function(element) {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2;
element.style.top = Math.max(0, topValue) + 'px';
element.dialogPolyfillInfo.isTopOverridden = true;
};
dialogPolyfill.inNodeList = function(nodeList, node) {
for (var i = 0; i < nodeList.length; ++i) {
if (nodeList[i] == node)
return true;
}
return false;
};
dialogPolyfill.isInlinePositionSetByStylesheet = function(element) {
for (var i = 0; i < document.styleSheets.length; ++i) {
var styleSheet = document.styleSheets[i];
var cssRules = null;
// Some browsers throw on cssRules.
try {
cssRules = styleSheet.cssRules;
} catch (e) {}
if (!cssRules)
continue;
for (var j = 0; j < cssRules.length; ++j) {
var rule = cssRules[j];
var selectedNodes = null;
// Ignore errors on invalid selector texts.
try {
selectedNodes = document.querySelectorAll(rule.selectorText);
} catch(e) {}
if (!selectedNodes || !dialogPolyfill.inNodeList(selectedNodes, element))
continue;
var cssTop = rule.style.getPropertyValue('top');
var cssBottom = rule.style.getPropertyValue('bottom');
if ((cssTop && cssTop != 'auto') || (cssBottom && cssBottom != 'auto'))
return true;
}
}
return false;
};
dialogPolyfill.needsCentering = function(dialog) {
var computedStyle = window.getComputedStyle(dialog);
if (computedStyle.position != 'absolute') {
return false;
}
// We must determine whether the top/bottom specified value is non-auto. In
// WebKit/Blink, checking computedStyle.top == 'auto' is sufficient, but
// Firefox returns the used value. So we do this crazy thing instead: check
// the inline style and then go through CSS rules.
if ((dialog.style.top != 'auto' && dialog.style.top != '') ||
(dialog.style.bottom != 'auto' && dialog.style.bottom != ''))
return false;
return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog);
};
dialogPolyfill.showDialog = function(isModal) {
if (this.open) {
throw 'InvalidStateError: showDialog called on open dialog';
}
this.open = true; // TODO: should be a getter mapped to attribute
this.setAttribute('open', 'open');
if (isModal) {
// Find element with `autofocus` attribute or first form control
var first_form_ctrl = null;
var autofocus = null;
var findElementToFocus = function(root) {
if (!root.children) {
return;
}
for (var i = 0; i < root.children.length; i++) {
var elem = root.children[i];
if (first_form_ctrl === null && !elem.disabled && (
elem.nodeName == 'BUTTON' ||
elem.nodeName == 'INPUT' ||
elem.nodeName == 'KEYGEN' ||
elem.nodeName == 'SELECT' ||
elem.nodeName == 'TEXTAREA')) {
first_form_ctrl = elem;
}
if (elem.autofocus) {
autofocus = elem;
return;
}
findElementToFocus(elem);
if (autofocus !== null) return;
}
};
findElementToFocus(this);
if (autofocus !== null) {
autofocus.focus();
} else if (first_form_ctrl !== null) {
first_form_ctrl.focus();
}
}
if (dialogPolyfill.needsCentering(this))
dialogPolyfill.reposition(this);
if (isModal) {
this.dialogPolyfillInfo.modal = true;
dialogPolyfill.dm.pushDialog(this);
}
// IE sometimes complains when calling .focus() that it
// "Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus."
try {
if (autofocus !== null) {
autofocus.focus();
} else if (first_form_ctrl !== null) {
first_form_ctrl.focus();
}
} catch(e) {}
this.style.zoom = 1;
};
dialogPolyfill.close = function(retval) {
if (!this.open && !window.HTMLDialogElement) {
// Native implementations will set .open to false, so ignore this error.
throw 'InvalidStateError: close called on closed dialog';
}
this.open = false;
this.removeAttribute('open');
// Leave returnValue untouched in case it was set directly on the element
if (typeof retval != 'undefined') {
this.returnValue = retval;
}
// This won't match the native <dialog> exactly because if the user sets top
// on a centered polyfill dialog, that top gets thrown away when the dialog is
// closed. Not sure it's possible to polyfill this perfectly.
if (this.dialogPolyfillInfo.isTopOverridden) {
this.style.top = 'auto';
}
if (this.dialogPolyfillInfo.modal) {
dialogPolyfill.dm.removeDialog(this);
}
// Triggering "close" event for any attached listeners on the <dialog>
var event;
if (document.createEvent) {
event = document.createEvent('HTMLEvents');
event.initEvent('close', true, true);
} else {
event = new Event('close');
}
this.dispatchEvent(event);
return this.returnValue;
};
dialogPolyfill.registerDialog = function(element) {
if (element.show) {
// console.warn("This browser already supports <dialog>, the polyfill " +
// "may not work correctly.");
}
element.show = dialogPolyfill.showDialog.bind(element, false);
element.showModal = dialogPolyfill.showDialog.bind(element, true);
element.close = dialogPolyfill.close.bind(element);
element.dialogPolyfillInfo = {};
element.open = false;
};
// The overlay is used to simulate how a modal dialog blocks the document. The
// blocking dialog is positioned on top of the overlay, and the rest of the
// dialogs on the pending dialog stack are positioned below it. In the actual
// implementation, the modal dialog stacking is controlled by the top layer,
// where z-index has no effect.
var TOP_LAYER_ZINDEX = 100000;
var MAX_PENDING_DIALOGS = 100000;
dialogPolyfill.DialogManager = function() {
this.pendingDialogStack = [];
this.overlay = document.createElement('div');
this.overlay.style.width = '100%';
this.overlay.style.height = '100%';
this.overlay.style.position = 'fixed';
this.overlay.style.left = '0px';
this.overlay.style.top = '0px';
this.overlay.style.backgroundColor = 'rgba(0,0,0,0.0)';
this.focusPageLast = this.createFocusable();
this.overlay.appendChild(this.focusPageLast);
this.overlay.addEventListener('click', function(e) {
var redirectedEvent = document.createEvent('MouseEvents');
redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window,
e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey,
e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
document.body.dispatchEvent(redirectedEvent);
});
// TODO: Only install when any dialogs are open.
document.addEventListener('submit', function(ev) {
var method = ev.target.getAttribute('method');
method = method ? method.toLowerCase() : '';
if (method != 'dialog') { return; }
ev.preventDefault();
var dialog = findNearestDialog(ev.target);
if (!dialog) { return; }
// FIXME: The original event doesn't contain the INPUT element used to
// submit the form (if any). Look in some possible places.
var returnValue;
var cands = [document.activeElement, ev.explicitOriginalTarget];
cands.some(function(cand) {
if (cand && cand.nodeName == 'INPUT' && cand.form == ev.target) {
returnValue = cand.value;
return true;
}
});
dialog.close(returnValue);
}, true);
};
dialogPolyfill.DialogManager.prototype.createFocusable = function(tabIndex) {
var span = document.createElement('span');
span.tabIndex = tabIndex || 0;
span.style.opacity = 0;
span.style.position = 'static';
return span;
};
dialogPolyfill.DialogManager.prototype.blockDocument = function() {
if (!document.body.contains(this.overlay)) {
document.body.appendChild(this.overlay);
// On Safari/Mac (and possibly other browsers), the documentElement is
// not focusable. This is required for modal dialogs as it is the first
// element to be hit by a tab event, and further tabs are redirected to
// the most visible dialog.
if (this.needsDocumentElementFocus === undefined) {
document.documentElement.focus();
this.needsDocumentElementFocus =
(document.activeElement != document.documentElement);
}
if (this.needsDocumentElementFocus) {
document.documentElement.tabIndex = 1;
}
}
};
dialogPolyfill.DialogManager.prototype.unblockDocument = function() {
document.body.removeChild(this.overlay);
if (this.needsDocumentElementFocus) {
// TODO: Restore the previous tabIndex, rather than clearing it.
document.documentElement.tabIndex = '';
}
};
dialogPolyfill.DialogManager.prototype.updateStacking = function() {
if (this.pendingDialogStack.length == 0) {
this.unblockDocument();
return;
}
this.blockDocument();
var zIndex = TOP_LAYER_ZINDEX;
for (var i = 0; i < this.pendingDialogStack.length; i++) {
if (i == this.pendingDialogStack.length - 1)
this.overlay.style.zIndex = zIndex++;
var dialog = this.pendingDialogStack[i];
dialog.dialogPolyfillInfo.backdrop.style.zIndex = zIndex++;
dialog.style.zIndex = zIndex++;
}
};
dialogPolyfill.DialogManager.prototype.handleKey = function(event) {
var dialogCount = this.pendingDialogStack.length;
if (dialogCount == 0) {
return;
}
var dialog = this.pendingDialogStack[dialogCount - 1];
var pfi = dialog.dialogPolyfillInfo;
switch (event.keyCode) {
case 9: /* tab */
var activeElement = document.activeElement;
var forward = !event.shiftKey;
if (forward) {
// Tab forward, so look for document or fake last focus element.
if (activeElement == document.documentElement ||
activeElement == document.body ||
activeElement == pfi.backdrop) {
pfi.focusFirst.focus();
} else if (activeElement == pfi.focusLast) {
// TODO: Instead of wrapping to focusFirst, escape to browser chrome.
pfi.focusFirst.focus();
}
} else {
// Tab backwards, so look for fake first focus element.
if (activeElement == pfi.focusFirst) {
// TODO: Instead of wrapping to focusLast, escape to browser chrome.
pfi.focusLast.focus();
} else if (activeElement == this.focusPageLast) {
// The focus element is at the end of the page (e.g., shift-tab from
// the window chrome): move current focus to the last element in the
// dialog instead.
pfi.focusLast.focus();
}
}
break;
case 27: /* esc */
event.preventDefault();
event.stopPropagation();
var cancelEvent = new supportCustomEvent('cancel', {
bubbles: false,
cancelable: true
});
if (dialog.dispatchEvent(cancelEvent)) {
dialog.close();
}
break;
}
};
dialogPolyfill.DialogManager.prototype.pushDialog = function(dialog) {
if (this.pendingDialogStack.length >= MAX_PENDING_DIALOGS) {
throw "Too many modal dialogs";
}
var backdrop = document.createElement('div');
backdrop.className = 'backdrop';
var clickEventListener = function(e) {
var redirectedEvent = document.createEvent('MouseEvents');
redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window,
e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey,
e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
dialog.dispatchEvent(redirectedEvent);
};
backdrop.addEventListener('click', clickEventListener);
dialog.parentNode.insertBefore(backdrop, dialog.nextSibling);
dialog.dialogPolyfillInfo.backdrop = backdrop;
dialog.dialogPolyfillInfo.clickEventListener = clickEventListener;
this.pendingDialogStack.push(dialog);
this.updateStacking();
dialog.dialogPolyfillInfo.focusFirst = this.createFocusable();
dialog.dialogPolyfillInfo.focusLast = this.createFocusable();
dialog.appendChild(dialog.dialogPolyfillInfo.focusLast);
dialog.insertBefore(
dialog.dialogPolyfillInfo.focusFirst, dialog.firstChild);
};
dialogPolyfill.DialogManager.prototype.removeDialog = function(dialog) {
var index = this.pendingDialogStack.indexOf(dialog);
if (index == -1) {
return;
}
this.pendingDialogStack.splice(index, 1);
var backdrop = dialog.dialogPolyfillInfo.backdrop;
var clickEventListener = dialog.dialogPolyfillInfo.clickEventListener;
backdrop.removeEventListener('click', clickEventListener);
backdrop.parentNode.removeChild(backdrop);
dialog.dialogPolyfillInfo.backdrop = null;
dialog.dialogPolyfillInfo.clickEventListener = null;
this.updateStacking();
dialog.removeChild(dialog.dialogPolyfillInfo.focusFirst);
dialog.removeChild(dialog.dialogPolyfillInfo.focusLast);
dialog.dialogPolyfillInfo.focusFirst = null;
dialog.dialogPolyfillInfo.focusLast = null;
};
dialogPolyfill.dm = new dialogPolyfill.DialogManager();
document.addEventListener('keydown',
dialogPolyfill.dm.handleKey.bind(dialogPolyfill.dm));
return dialogPolyfill;
})();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
require("/node_modules/meteor/ohif:viewerbase/client/components/basic/layout/template.layout.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/basic/loadingText/template.loadingText.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/basic/errorText/template.errorText.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/basic/removableBackdrop/template.removableBackdrop.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/basic/aboutModal/template.aboutModal.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/basic/aboutModal/aboutModal.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/studyBrowser/studyBrowser/template.studyBrowser.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/studyBrowser/thumbnailEntry/template.thumbnailEntry.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/studyBrowser/imageThumbnail/template.imageThumbnail.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/studyBrowser/imageThumbnail/imageThumbnail.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/imageViewerViewport/template.imageViewerViewport.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/gridLayout/template.gridLayout.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/gridLayout/gridLayout.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/loadingIndicator/template.loadingIndicator.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/loadingIndicator/loadingIndicator.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/annotationDialogs/template.annotationDialogs.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/annotationDialogs/annotationDialogs.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/viewportOrientationMarkers/template.viewportOrientationMarkers.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/viewportOverlay/template.viewportOverlay.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/viewportOverlay/viewportOverlay.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/viewerMain/template.viewerMain.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/viewerMain/viewerMain.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/toolContextMenu/toolContextMenu.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/imageControls/template.imageControls.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/imageControls/imageControls.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/layoutButton/template.layoutButton.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/layoutButton/layoutButton.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/layoutChooser/template.layoutChooser.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/layoutChooser/layoutChooser.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/cineDialog/template.cineDialog.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/cineDialog/cineDialog.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/downloadDialog/template.downloadDialog.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/downloadDialog/downloadDialog.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/toolbarSectionButton/template.toolbarSectionButton.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/toolbarSectionButton/toolbarSectionButton.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/toolbarSectionTools/template.toolbarSectionTools.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/toolbarSectionTools/toolbarSectionTools.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/userPreferences/template.dialog.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/userPreferences/dialog.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/confirmDeleteDialog/template.confirmDeleteDialog.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/confirmDeleteDialog/confirmDeleteDialog.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/textMarkerDialogs/template.textMarkerDialogs.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/textMarkerDialogs/textMarkerDialogs.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/seriesQuickSwitch/template.seriesQuickSwitch.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/studySeriesQuickSwitch/template.studySeriesQuickSwitch.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/studySeriesQuickSwitch/studySeriesQuickSwitch.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/studyTimepointBrowser/template.studyTimepoint.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepoint.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/studyTimepointBrowser/template.studyTimepointBrowser.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/studyTimepointBrowser/template.studyTimepointStudy.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointStudy.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/windowLevelPresets/template.form.js");
require("/node_modules/meteor/ohif:viewerbase/client/components/viewer/windowLevelPresets/form.js");
var exports = require("/node_modules/meteor/ohif:viewerbase/main.js");
/* Exports */
Package._define("ohif:viewerbase", exports, {
dialogPolyfill: dialogPolyfill
});
})();