Sicker and younger: Toronto ICU copes with pressure during third wave of pandemic – The Globe and Mail

The spike in cases has strained intensive care capacity across Ontario, prompting discussions about the possible need to triage life-saving care. There are about 50 patients in Humber River’s ICU on April 13, more than 60 per cent of them with COVID-19, says Raman Rai, who manages the ICU. Staffing has become a challenge as exhausted nurses seek time off to rest. Transfers from other units have helped alleviate some pressure but Rai says she still worries about staffing, especially the lack of ICU-trained nurses. Across the province, there were 644 patients with COVID-19-related critical illness in intensive care beds as of April 15, according to Critical Care Services Ontario. The government has promised to create up to 1,000 more ICU beds in response to the growing need. The Canadian Press photographer Nathan Denette captures ICU workers, in hard-hit Toronto, who are witnessing the human side of the startling numbers firsthand.

A 60-year-old COVID-19 patient fights for his life, desperately gasping for air as head intensivist Dr. Ali Ghafouri provides life saving medical care at the Humber River Hospital during the COVID-19 pandemic in Toronto on Tuesday, April 13, 2021. The patient was intubated and put on a ventilator successfully.

Nathan Denette/The Canadian Press

1 of 13

Humber River Hospital health-care staff provide medical care for a COVID-19 patient in Toronto on Tuesday, April 13, 2021.

Nathan Denette/The Canadian Press

2 of 13

Health-care staff get ready to prone a 47-year-old woman who has COVID-19 and is intubated on a ventilator in the intensive care unit.

Nathan Denette/The Canadian Press

3 of 13

Registered nurse Jane Abas tends to a COVID-19 variant patient who is intubated and on a ventilator.

Nathan Denette/The Canadian Press

4 of 13

Story continues below advertisement

Olivia Coughlin, a registered health-care social worker, calls the family of a COVID-19 patient who’s in critical condition.

Nathan Denette/The Canadian Press

5 of 13

A COVID-19 patient fights to breathe. The patient was intubated and put on a ventilator successfully.

Nathan Denette/The Canadian Press

6 of 13

Registered nurse Jane Abas tends to a COVID-19 variant patient.

Nathan Denette/The Canadian Press

7 of 13

Nurse Abas watches over a COVID-19 variant patient.

Nathan Denette/The Canadian Press

8 of 13

A health-care worker takes his break in the ICU’s staff lounge.

Nathan Denette/The Canadian Press

9 of 13

Registered nurse Claire Wilkinson tends to a 47-year-old woman who has COVID-19 and is intubated on a ventilator in the ICU at the Humber River Hospital.

Nathan Denette/The Canadian Press

10 of 13

A 47-year-old woman who has COVID-19 has been intubated and is now on a ventilator.

Nathan Denette/The Canadian Press

11 of 13

An essential worker thoroughly cleans a COVID-19 patient’s room after being transferred out of the ICU.

Nathan Denette/The Canadian Press

12 of 13

Registered nurse Stephanie Flores, who has been redeployed from the operating room to the ICU, looks out the window in the ICU at the Humber River Hospital.

Nathan Denette/The Canadian Press

13 of 13

‘,
”,
].join(”)

var renderPaywall = function () {
return paywallInnerHTML;
}

setKeytarWall(paywallType.type, ‘teaser’, {template: renderPaywall});

}

// mobile intersitital
function renderFsaleMobileInterstitial(variant, tag) {

var code = variant === ‘expA’ ? ‘_c_b’ : ‘_b’
document.getElementsByTagName(‘body’)[0].className += ” u-no-scroll modal-open”;

var newNode = document.createElement(‘div’);
newNode.setAttribute(‘id’, ‘fsale-modal’);
newNode.className = ‘o-modal-outer-container o-modal-outer-container–opened’;

document.getElementById(‘pb-root’).appendChild(newNode);
document.getElementById(‘fsale-modal’).innerHTML = [
‘,

‘,
‘,
Flash sale! $0.99 per week for 24 weeks. Offer ends Aprial 20, 2021‘,
‘,

‘,
].join(”);

// dark background:
var bgdark = document.createElement(‘div’);
bgdark.setAttribute(“class”, “c-lightbox”);
bgdark.setAttribute(“id”, “firstvisit-bgdark”);
var refNode = document.getElementById(“fsale-modal”);
refNode.parentNode.insertBefore(bgdark, refNode);

pushAnalytics(‘cem1896’, ‘fsale’, ‘modalDisplay-‘ + variant, ‘modalDisplay-‘ + variant, variant,
‘fsale’);
}

//close mobile intersitital function
function closeFsaleMobileInterstitial() {
document.getElementById(‘fsale-modal’).className = ‘ u-hidden’;
document.getElementById(‘firstvisit-bgdark’).className = ‘ u-hidden’;
document.getElementsByTagName(‘body’)[0].classList.remove(‘u-no-scroll’, ‘modal-open’);
}

//update subscribe btn:
function updateFsaleSubscribeCTA() {
var deskBtn = document.getElementById(‘c-site-header-subscribe-button–non-mobile’);
var mobBtn = document.getElementById(‘c-site-header-subscribe-button–mobile’);
if (deskBtn && deskBtn.getElementsByTagName(‘span’) && deskBtn.getElementsByTagName(‘span’)[0] !== null && mobBtn) {
deskBtn.getElementsByTagName(‘span’)[0].innerHTML = “Flash Sale
$0.99/24wks”;
deskBtn.setAttribute(“onclick”,
“window.location.href=’https://subscribe.theglobeandmail.com/#/digital?intcmp=subscriberbtn'”);
deskBtn.id = ‘c-site-header-subscribe-button–non-mobile-fsale’;
mobBtn.remove();
}
}
setTimeout(updateFsaleSubscribeCTA, 3000);

“,


].join(“”);
}
return template;
}

/**
* Generate a template for the label
* @param {String} label – the label text
* @returns {String}
*/
function displayLabel(label) {
var template = “”;
if (label === “opinion”) {
template = [

“,
“, label, ““,

“,
].join(“”);
}
return template;
}

/**
* Display “Follow”, “Following” buttons
* @param {Object} tData
* @returns {String}
*/
function displayFollowingButton(tData) {
var topicName = tData.topicName;
var topicSlug = tData.topicSlug;
var topicType = tData.topicType;
var topicImg = tData.topicImg;
var isAuthor = topicType === “author”;
var authorImg = isAuthor && topicImg
? “" + topicName + "
: “”;
var template = isAuthor ? “/authors/” : “/topics/”;
var href = window.tgam.env.baseRootAbsoluteUrl + template + topicSlug;
var linkClasses = isAuthor ? “c-topic-link c-topic-link–author” : “c-topic-link”;
return [
” “,
].join(“”);
}

/**
* Generates story card markup
* @param {Object} article – to display
* @param {Object} topicData – (topicName, topicSlug, topicType, topicVariation, topicImg)
* @param {Boolean} addFollowButton
* @returns {String} story card markup
*/
function storyCard(article, topicData, addFollowButton) {
// console.info(“[ARC-7231] storyCard”, { article: article, topic: topicData });
if (!article || !topicData) {
return “”;
}
var tName = topicData.topicName;
var tType = topicData.topicType;
var tVariation = topicData.topicVariation;
var followingTopic;
var timeTemplate;
var analyticsModifier = tType + “: “;

if (addFollowButton) {
// Display a follow button beside the topic name
followingTopic = displayFollowingButton(topicData);
timeTemplate = displayDateTag(article);
}
var label = getLabel(article);
var image = getImage(article, label);
var labelTemplate = displayLabel(label);
var imageTemplate = displayImage(image);
var headline = article.headlines.basic;
var href = window.tgam.env.baseUrl + article.canonical_url;
var sophiId = article._id;

var dataAnalyticsClick = JSON.stringify({
type: “link”,
feature: “following feed”,
contentId: sophiId,
label: analyticsModifier + tName.toLowerCase() + “: ” + headline.toLowerCase(),
page: “sec:homepage:personalized feed:” + tVariation,
hierarchy: 1
});

var cardMarkup = “”;
if (!followingTopic) {
cardMarkup = [
“,

“,

“,
“, tName, ““,

“,

“,
“, headline, ““,

“,
labelTemplate,

“,

“, imageTemplate, “

“,

].join(“”);
} else {
cardMarkup = [

“,
followingTopic,

“,
“,

“,

“,
“, headline, ““,

“,
“, timeTemplate, ““,

“,

“, imageTemplate, “

“,
“,
].join(“”);
}
return [

“,
cardMarkup,

“,
].join(“”);
}

/**
* Adds the overlay trigger dot class
* @param {String} type – “unread” or “no-follow”
*/
function addOverlayTriggerDot(type) {
overlayTriggerDotClasses.forEach(function fn(dotClass) {
if (dotClass === “c-your-globe__trigger–dot–” + type) {
overlayTrigger.classList.add(dotClass);
} else {
overlayTrigger.classList.remove(dotClass);
}
});
overlayTrigger.classList.add(“c-your-globe__trigger–dot”);
}

/**
* Removes the overlay trigger dot class
*/
function removeOverlayTriggerDot() {
overlayTriggerDotClasses.forEach(function fn(dotClass) {
overlayTrigger.classList.remove(dotClass);
});
overlayTrigger.classList.remove(“c-your-globe__trigger–dot”);
}

/**
* Returns a heading element to be displayed inside the overlay
* @param {String} text
* @returns {String}
*/
function overlayLabel(text) {
return “

” + text + “

“;
}

var overlayHeadingHasFollowed = (
overlayLabel(“The latest in topics and authors you follow”) +

View more in Following


);

var overlayHeadingNoFollowed = (
overlayLabel(“Get started: build your personal news feed”) +

    ” +

  1. Follow topics relevant to your reading interests.
  2. ” +

  3. Check back here or your Following page to view the latest articles on your topics.
  4. ” +


);

var upToDateMessage = “

You’re up to date on your Following feed. Check again later for new stories.

“;

// ************************************************
// Parse API response and inject markup into overlay
// ************************************************

// Story card markup

/**
* Stories originally came from the following locations in the API response:
* – data.articles[i].items[i].topics
* – data.articles[i].items[i].authors
* @param {Array} stories
* @returns {String} story card markup
*/
function latestStoryCards(stories) {
console.info(“[ARC-7231] Display latest stories based on these stories:”, stories);

var storyCards = stories.map(function fn(story) {
// The “topics” and “authors” arrays will only contain one item
// (i.e. the topic or author that the user is following)
var topic;
var topicData;

if (story.topics && story.topics.length) {
// Normal topic
topic = story.topics[0];
topicData = {
topicName: topic.name,
topicSlug: topic.slug,
topicType: “topic”,
topicVariation: “following”
};
} else if (story.authors && story.authors.length) {
// Author topic
topic = story.authors[0];
// Only authors have images associated with them – normal topics do not
var authorImg = topic.metadata && topic.metadata.image ? topic.metadata.image : null;
topicData = {
topicName: topic.byline,
topicSlug: topic.slug,
topicType: “author”,
topicVariation: “following”,
topicImg: authorImg
};
}
// Don’t display a follow button beside the topic because the user is already following it
return storyCard(story, topicData, false);
}).join(“”);

return storyCards;
}

/**
* @param {Array} topics
* @param {String} variation – “recommended” or “trending” (used for the click tracking analytics)
* @returns {String} story card markup
*/
function recommendedTrendingStoryCards(topics, variation) {
var uniqueStories = generateUniqueStory(topics);
var storyCards = uniqueStories.map(function fn(topic) {
// Grab one article
var story = topic.items[0];
// Only authors have images associated with them – normal topics do not
var authorImg = topic.authorTopic && topic.authorMetadata && topic.authorMetadata.image
? topic.authorMetadata.image
: null;
// Normally we’d display all of the topics that are assigned to an article, but
// this API groups articles by topic, so we only have access to that one topic.
// Even if we could display additional topics, we wouldn’t want to becuase having
// multiple follow buttons would junk up the UI.
var topicData = {
topicName: topic.name,
topicSlug: topic.slug,
topicType: topic.authorTopic ? “author” : “topic”,
topicVariation: variation,
topicImg: authorImg
};
// Display the follow button beside the topic because we’re suggesting new topics to follow
return storyCard(story, topicData, true);
}).join(“”);

return storyCards;
}

/**
* Topics originally came from the following locations in the API response:
* – data.recommendedAuthors
* – data.recommendedTopics
* @param {Array} topics
* @returns {String} story card markup
*/
function recommendedStoryCards(topics) {
console.info(“[ARC-7231] Display recommended stories based on these topics:”, topics);
return recommendedTrendingStoryCards(topics, “recommended”);
}

/**
* Topics originally came from the following location in the API response:
* – data.trendingTopics
* @param {Array} topics
* @returns {String} story card markup
*/
function trendingStoryCards(topics) {
console.info(“[ARC-7231] Display trending stories based on these topics:”, topics);
return recommendedTrendingStoryCards(topics, “trending”);
}

// Markup inside the overlay

/**
* @param {Array} stories
* @returns {Object} markup for the overlay’s header and body content areas
*/
function showLatestStories(stories) {
console.info(“[ARC-7231] Scenario: latest stories”);
var storyCardsMarkup = latestStoryCards(stories);
return {
header: overlayHeadingHasFollowed,
body: storyCardsMarkup
};
}

/**
* @param {Array} topics
* @returns {Object} markup for the overlay’s header and body content areas
*/
function upToDateShowRecommended(topics) {
console.info(“[ARC-7231] Scenario: up to date, show recommended”);
var storyCardsMarkup = recommendedStoryCards(topics);
return {
header: overlayHeadingHasFollowed,
body: (
upToDateMessage +
overlayLabel(“Recommended for you”) +
storyCardsMarkup
)
};
}

/**
* @param {Array} topics
* @returns {Object} markup for the overlay’s header and body content areas
*/
function upToDateShowTrending(topics) {
console.info(“[ARC-7231] Scenario: up to date, show trending”);
var storyCardsMarkup = trendingStoryCards(topics);
return {
header: overlayHeadingHasFollowed,
body: (
upToDateMessage +
overlayLabel(“Trending topics to follow”) +
storyCardsMarkup
)
};
}

/**
* @param {Array} topics
* @returns {Object} markup for the overlay’s header and body content areas
*/
function notFollowingShowRecommended(topics) {
console.info(“[ARC-7231] Scenario: not following, show recommended”);
var storyCardsMarkup = recommendedStoryCards(topics);
return {
header: overlayHeadingNoFollowed,
body: (
overlayLabel(“Recommended for you”) +
storyCardsMarkup
)
};
}

/**
* @param {Array} topics
* @returns {Object} markup for the overlay’s header and body content areas
*/
function notFollowingShowTrending(topics) {
console.info(“[ARC-7231] Scenario: not following, show trending”);
var storyCardsMarkup = trendingStoryCards(topics);
return {
header: overlayHeadingNoFollowed,
body: (
overlayLabel(“Trending topics to follow”) +
storyCardsMarkup
)
};
}

/**
* Parse data from the personalized API and inject markup into the overlay
* @see https://confluence.theglobeandmail.com/display/ARC/Logic+for+Embedded+on+Homepage++and+Your+Globe+Overlay
* @param {Object} data – topic and story data provided by the API
* @param {String} hashId – user’s hash id
*/
function parsePerzonalizedTopicsData(data, hashId) {
console.info(“[ARC-7231] parsePerzonalizedTopicsData”, data);

var totalTopicsFollowed = data.totalTopicsFollowed || 0;
var totalAuthorsFollowed = data.totalAuthorsFollowed || 0;
var recommendedTopics = data.recommendedTopics || [];
var recommendedAuthors = data.recommendedAuthors || [];
var latestStories = data.articles || [];
var topics = [];
var stories = [];
var markup = “”;

if (totalTopicsFollowed || totalAuthorsFollowed) {
if (latestStories.length) {
// Scenario 1: “Latest stories”

// Count the number of stories returned (for logging/debugging purposes only)
var latestStoriesCount = latestStories.reduce(function _reduceStories(accumulator, date) {
var urls = date.items.map(function _mapStories(article) {
return article.canonical_url;
});
return accumulator.concat(urls);
}, []).length;
console.info(“[ARC-7231] latestStoryUrls (” + latestStoriesCount + “)”);

// Fetch the user’s reading history
// TODO: this API request will no longer be necessary when Data Science makes
// the “isRead” property functional (it’s currently “false” 100% of the time)
getReadingHistory(hashId).then(function _historyFetched(historyData) {
var readingHistoryUrls = historyData.map(function _mapHistory(item) {
return item.url;
});
console.info(“[ARC-7231] readingHistoryUrls (” + readingHistoryUrls.length + “)”);
var currentArticleUrl = window.tgam.meta.pagetype === “story” ? window.tgam.meta.urlRelative : null;

// Filter out stories that exist in the user’s reading history
var filteredStories = latestStories.map(function _mapDates(dateObj) {
var items = dateObj.items.filter(function _filterStories(article) {
var articleUrl = article.canonical_url;
var shouldRemove = readingHistoryUrls.includes(articleUrl) || article.isRead || articleUrl === currentArticleUrl;
if (shouldRemove) {
if (articleUrl === currentArticleUrl) {
console.info(“[ARC-7231] Currently reading this article, so removing: ” + articleUrl);
} else {
console.info(“[ARC-7231] Has already been read, so removing: ” + articleUrl);
}
}
return !shouldRemove;
});
return {
date: dateObj.date,
items: items
};
}, []);

stories = generateLatestStories(filteredStories);
markup = showLatestStories(stories);

var atLeastOneStoryIsNew = isLocalStorageSupported() ? checkNewStories(stories) : true;
if (atLeastOneStoryIsNew) {
// Display indicator only when there is a new story since the last time the user checked the feed
addOverlayTriggerDot(“unread”);
}
populateOverlay(markup, true);
});
} else {
if (recommendedTopics.length || recommendedAuthors.length) {
// Scenario 2: “Up to date, show recommended”
topics = recommendedAuthors.concat(recommendedTopics);
markup = upToDateShowRecommended(topics);
} else {
// Scenario 3: “Up to date, show trending”
topics = data.trendingTopics || [];
markup = upToDateShowTrending(topics);
}
populateOverlay(markup, true);
}
} else {
topics = recommendedAuthors.concat(recommendedTopics);
if (topics.length) {
// Scenario 4: “Not following, show recommended”
markup = notFollowingShowRecommended(topics);
} else {
// Scenario 5: “Not following, show trending”
topics = data.trendingTopics || [];
markup = notFollowingShowTrending(topics);
}
addOverlayTriggerDot(“no-follow”);
populateOverlay(markup, false);
}
}

/**
* Populate the overlay with content and activate the “following” functionality
* @param {String} markup – HTML markup
* @param {Boolean} headerBorder – whether to include a header border
*/
function populateOverlay(markup, headerBorder) {
var overlayHeader = qs(“.c-your-globe__overlay-header”);
var overlayHeaderText = qs(“.c-your-globe__overlay-header-text”);
var overlayBody = qs(“.c-your-globe__overlay-body”);

if (!overlayHeader || !overlayHeaderText || !overlayBody) {
return;
}
console.info(“[ARC-7231] Append markup”);

var spinner = qs(“.c-spinner”);
spinner && spinner.parentElement.removeChild(spinner);

overlayHeaderText.insertAdjacentHTML(“afterbegin”, markup.header);
overlayBody.insertAdjacentHTML(“afterbegin”, markup.body);

if (!headerBorder) {
overlayHeader.classList.add(“c-your-globe__overlay-header–no-border”);
}
addFollowingFunctionality();
}

// ************************************************
// API calls
// ************************************************

// Reading History API

/**
* Validate a response has an “ok” status, and is in the range 200-299 inclusive.
* @param {Response} response – to validate
* @returns {Promise

Leave a Reply

Your email address will not be published. Required fields are marked *