How to lose weight when you can’t get motivated

wafi jr
Man on treadmill chasing cupcake
Photo illustration by Slate. Photos by Ljupco/iStock/Getty Images Plus and stargatechris/iStock/Getty Images Plus.

John thinks he knows the formula for losing weight: increase his exercise and quit the peanut M&M’s. He has a strong incentive to get fit—at 72 and about to retire, he wants not only to have more energy to play pickleball and travel, but also to reduce his blood pressure medication. But for some reason, John can’t stay in the right headspace to actually make the change. On a recent episode of How To!, Katy Milkman, a behavioral economist at the University of Pennsylvania and host of the podcast Choiceology, shares the science behind why we hold ourselves back from making real change and, moreover, how we can engineer our way into healthier, happier lives. With the right set up, the most difficult things—like losing weight—may be easier and more enjoyable than we thought. This transcript has been condensed and edited for clarity.

Charles Duhigg: Katy, what was your path to studying how people change their behaviors?
Katy Milkman: My passion was engineering, but I found myself outside of the classroom wondering about self-control problems that I had and that my friends had. I was always curious—why we can solve very sophisticated problems and build bridges effectively, but we can’t solve our own very simple problems?

I had issues trying to get myself to the gym at the end of a long day. I was a very competitive tennis player in high school and college, but I quit the varsity tennis team halfway through college. I still really wanted to stay in shape, but I struggled to find ways to get myself to the gym at the end of a long day of classes because I was tired. All I really wanted to do was lie down on the couch and watch TV or curl up with a good book. I realized maybe I can solve both of these problems in the very same way. So I concocted a scheme where I allowed myself only to enjoy those kinds of indulgences—specifically I got really into audio novels—when I was exercising. I would come home from a long day and I would find myself looking forward to a workout because I was gonna get to find out what happens next in my latest novel. Time flew when I was at the gym. It was really fun to workout. I call that “temptation bundling” and I’ve studied it and showed that it’s not just me—it can be useful for other people as well.

Charles: John, what do you feel like you’re struggling with the most when it comes to weight loss? Is there something you could apply this idea of temptation bundling to?

John: Right now I find that one of my challenges is my wife, my second marriage. With the pandemic, my wife has been cooking cakes, so I’m not watching my meals and I’m eating unhealthy snacks or too much or the wrong food. If there’s sugary things in the house, then that’s where I migrate. The other day, for instance, our daughter-in-law brought us food from the store and at the last minute my wife says, “Oh, get a big jar of peanut M&M’s.”

Charles: Oh no.

John: They sit there on the counter. Since last Saturday I’ve done great because I visualized that my wife had sneezed in the container! I thought, “Oh no way am I going to have a handful of those now.” And then last night I just had to have a handful of peanut M&M’s. If they hadn’t been there, I never would’ve thought of that.

Katy: Food is a tough one. When I use it in temptation bundling, it’s usually the temptation component. What you can do is find a way to ensure that for every meal you have options ready that you are going to enjoy even if they aren’t peanut M&Ms. Another big thing to think about is restricting your access to that unhealthy food. It sounds like your environment is filled with temptations if you’ve got these peanut M&M’s on the counter and your wife is baking cakes. I think you need to work with your wife on creating that environment in your home so that you purge the unhealthy snacks as much as possible or put them in a locked cabinet that she’s got the combination for, so if she doesn’t want to restrict herself, there’s a way to restrict you at least.

Charles: If you went to your wife and you said, “Honey, I love you. But I don’t love the fact that there are cakes around me. Can we take all the sweets and put them in a locked cabinet? And you have the key.” How do you think she’d react to that?

John: In general, I think she’d be supportive. We dated in high school, went our separate ways, then got back together 40 years later. In some ways, it’s a perpetual honeymoon, but in a couple of ways, there are some challenges in our relationship. She’s more in the camp of “we are who we are and we can’t change.” And I’m more in the camp of “Oh, we can always change. That’s what life is all about.” And we kind of butt heads over that sometimes. When it gets distilled down to talking about eating, if I want to pay a lot of attention to the food I eat, she sees it as obsessing. I know she feels hurt if I don’t want to eat whatever she cooks, so I haven’t actually talked to her about some of these things. But I absolutely need to do that. I will actually. I will commit to doing that.

Charles: Katy, what John is saying makes sense—the things that we struggle with are so influenced by the people around us and in their attitudes to the change that we’re trying to create. What do we know about the science behind this? 

Katy: Absolutely. It’s so social. We have a lot of evidence supporting everything you just said— the people around us are a huge contributor to our behavior. So if everybody around you starts eating more, you’re much more likely to do the same and vice versa. John, if your wife decided she wanted to cut back, you would be likely to eat a little bit less and lose a little bit more. Trying to get on the same page is going to be really valuable for your success. With my dad, for example, I’ve been very worried about his physical activity levels, so I convinced him to buy a Fitbit, which I also have. We have the ability to see each other’s steps—and he knows I’m watching. In fact, he confessed to me that his steps weren’t uploading and he spent 2 hours on the phone with Fitbit support because he was so upset that I would think he hadn’t walked enough that day.

Often a big opportunity is to figure out a third-party perspective on any kind of disagreement you’re currently having with your partner. How would another person see this conflict and what would they think? This can help relieve some of the emotional tension. Maybe see if your wife would be open to thinking about your desire to lose weight from a third-party perspective. [Especially as you approach your retirement], this moment can feel like a breaking point from normal moments. I’ve done research on the moments when people are more likely to try to make a change in their lives, and what we’ve found is the start of a new era, the start of your retirement years, the start of a new decade, even something as trivial as the start of a new week, help us step back and think big picture. What are our goals? That motivates us to start new projects and feel more separated from our past failings. For example, I had always wanted to write a book and just hadn’t gotten up the nerve to do it. At the same time, my husband and I had been thinking about moving. We had a young son. We were ready to be out of an apartment and into a house. The day that we signed and became owners of a new house is the day that I sent out emails to agents and started the book-writing process. I just finished writing a book called How to Change. So the new house was the thing that pushed me over. It was a new era.

Charles: Okay, but what happens when the fresh start doesn’t work so smoothly? 

Katy: Yes, you’re going to slip up. Nobody’s perfect. One risk when you make plans to change like this is something called the “what-the-hell” effect. (I love that there’s an academic term called the “what-the-hell” effect.) A challenge with this kind of rigid plan is you’ll never actually live up to all of your objectives. A big problem can be when you slip up saying, “Oh, what the hell, I give up.” If you have a plan for the day and you eat a cinnamon bun for breakfast because your wife just made a beautiful cinnamon bun, then you say, “Oh, what the hell? Let me just have a steak and fries and pie for lunch.” So when you have a plan you also have to think what will happen when you slip off track. What will you do? How will you get back on track? How will you forgive yourself? And how do you avoid slipping off track all the time and being too forgiving? There’s a sort of tightrope you have to walk. But if you can make progress for a month, even when you lose motivation little, you probably won’t fall all the way off the wagon because you do build some habits. In my studies, about 30 percent of the behaviors we start doing for a month around, say, exercise, tend to stick—even if all of the tricks we’ve been using to put those good behaviors in place are pulled away. Habit can be really helpful.

Just one last thing to keep in mind is something called a commitment device. There are actually a couple of different websites you can use where you can put money down that you’ll forfeit—or even send to a charity you hate—if you fail to achieve some stated goal. Nike has made the “Just Do It” model such a part of our culture. But the research so consistently shows that it’s just not that easy. Our motivation does wax and wane. We need these systems. You have to recognize that it won’t be easy to just do it. Willpower is hard. When you see that temptation, you reach for it. So the more you can do to structure the choices to help yourself, the better.

John: That might actually work. If I was going to commit $500 to Donald Trump’s campaign, I think I would lose the weight in two days.

Subscribe to How To! on Apple Podcasts, Spotify, or Stitcher

To hear Katy help John find the words to convince his wife to stop baking so many sweets, listen to the episode by clicking the player below or subscribing to How To! with Charles Duhigg wherever you get your podcasts.

nnx3c!-- Rubicon Project Ad Tag --x3en


nn")), n = v(f[r.size_id].split("x").map(function (e)
return Number(e);
), 2), i.width = n[0], i.height = n[1]), i.rubiconTargeting = (Array.isArray(r.targeting) ? r.targeting : []).reduce(function (e, r)
return e[r.key] = r.values[0], e;
rpfl_elemid: s.adUnitCode
), e.push(i)) : g.logError("Rubicon: bidRequest undefined at index position:".concat(t), c, d), e;
, []).sort(function (e, r) 0);
getUserSyncs: function getUserSyncs(e, r, t, i)
if (!R && e.iframeEnabled)
var n = "";
return t && "string" == typeof t.consentString && ("boolean" == typeof t.gdprApplies ? n += "?gdpr=".concat(Number(t.gdprApplies), "&gdpr_consent=").concat(t.consentString) : n += "?gdpr_consent=".concat(t.consentString)), i && (n += "".concat(n ? "&" : "?","us_privacy=").concat(encodeURIComponent(i))), R = !0,
type: "iframe",
url: a + n

transformBidParams: function transformBidParams(e)
return g.convertTypes(
accountId: "number",
siteId: "number",
zoneId: "number"
, e);


function _(e, r)

function I(e, r)
var t = b.b.getConfig("pageUrl"),
t = e.params.referrer ? e.params.referrer : t

function A(e, r)
var t = e.params;

if ("video" === r)
var i = [];
return && && ? i = [,] : Array.isArray(g.deepAccess(e, "")) && 1 === ? i =[0] : Array.isArray(e.sizes) && 0 < e.sizes.length && Array.isArray(e.sizes[0]) && 1 < e.sizes[0].length && (i = e.sizes[0]), i; var n = []; return Array.isArray(t.sizes) ? n = t.sizes : void 0 !== g.deepAccess(e, "mediaTypes.banner.sizes") ? n = s(e.mediaTypes.banner.sizes) : Array.isArray(e.sizes) && 0 < e.sizes.length ? n = s(e.sizes) : g.logWarn("Rubicon: no sizes are setup or found"), S(n); function s(e) return g.parseSizesInput(e).reduce(function (e, r) var t = parseInt(f[r], 10); return t && e.push(t), e; , []); function c(e) return "object" === x(g.deepAccess(e, "")) && void 0 !== g.deepAccess(e, "mediaTypes.".concat(u.d)); function m(e, r) var t = 1 < arguments.length && void 0 !== r && r; return c(e) ? -1 === ["outstream","instream"].indexOf(g.deepAccess(e, "mediaTypes.".concat(u.d, ".context"))) ? void (t && g.logError("Rubicon: must be outstream or instream")) : A(e, "video").length < 2 ? void (t && g.logError("Rubicon: could not determine the playerSize of the video")) : (t && g.logMessage("Rubicon: making video request for adUnit", e.adUnitCode), "video") : 0 === A(e, "banner").length ? void (t && g.logError("Rubicon: could not determine the sizes for banner request")) : (t && g.logMessage("Rubicon: making banner request for adUnit", e.adUnitCode), "banner"); function S(e) var n = [15, 2, 9]; return e.sort(function (e, r) -1 < i ? -1 === t ? 1 : -1 === i ? -1 : t - i : e - r; ); function C(e) var r = parseInt(g.deepAccess(e, "")); return isNaN(r) ? "outstream" === g.deepAccess(e, "mediaTypes.".concat(u.d, ".context")) ? 203 : 201 : r; function j(e) return ranges: low: [ max: 5, increment: .5 ], medium: [ max: 20, increment: .1 ], high: [ max: 20, increment: .01 ], auto: [ max: 5, increment: .05 , min: 5, max: 10, increment: .1 , min: 10, max: 20, increment: .5 ], dense: [ max: 3, increment: .01 , min: 3, max: 8, increment: .05 , min: 8, max: 20, increment: .5 ], custom: e.getConfig("customPriceBucket") && e.getConfig("customPriceBucket").buckets [e.getConfig("priceGranularity")] ; function k(r) var t = !0, e =[]), i =, n = mimes: e, protocols: e, maxduration: i, linearity: i, api: e ; return Object.keys(n).forEach(function (e), "" + e)) !== n[e] && (t = !1, g.logError("Rubicon:" + e + " is required and must be of type: " + n[e])); ), t; function T(e) function w(e, r) return "rp_schain" === e ? "rp_schain=".concat(r) : "".concat(e, "=").concat(encodeURIComponent(r)); var R = !1; Object(i.registerBidder)(h); } }, [677]); pbjsChunk([93], { 719: function _(e, t, r) e.exports = r(720); , 720: function _(e, t, r) { "use strict"; Object.defineProperty(t, "__esModule", value: !0 ), r.d(t, "spec", function () return o; ), r.d(t, "_isInbounds", function () return a; ), t._getPlatform = v; var n = r(1), y = r(0), i = r(2), c = r(3), g = r(10), d = r(44); function h(e, t) function s(e, t) t > e.length) && (t = e.length);

for (var r = 0, n = new Array(t); r < t; r++) n[r] = e[r]; return n; function u() function (e) for (var t = 1; t < arguments.length; t++) var r = arguments[t]; for (var n in r), n) && (e[n] = r[n]); return e; ).apply(this, arguments); function p(e, t, r) return t in e ? Object.defineProperty(e, t, value: r, enumerable: !0, configurable: !0, writable: !0 ) : e[t] = r, e; var b = "sonobi", l = Object(y.generateUUID)(), o = { code: b, supportedMediaTypes: [i.b, i.d], isBidRequestValid: function isBidRequestValid(e) if (!e.params) return !1; if (!e.params.ad_unit && !e.params.placement_id) return !1; if (!Object(y.deepAccess)(e, "mediaTypes.banner") && !Object(y.deepAccess)(e, "")) return !1; if (Object(y.deepAccess)(e, "mediaTypes.banner")) if (!Object(y.deepAccess)(e, "mediaTypes.banner.sizes") && !e.params.sizes) return !1; else if (Object(y.deepAccess)(e, "")) if ("outstream" === Object(y.deepAccess)(e, "") && !e.params.sizes) return !1; if ("instream" === Object(y.deepAccess)(e, "") && !Object(y.deepAccess)(e, "")) return !1; return !0; , buildRequests: function buildRequests(e, t) var r = (e) ").concat(e.bidId), "".concat(f(e)).concat(m(e)))) : /^[0-9a-fA-F]20$/.test(t) && 20 === t.length ? p(, e.bidId, "".concat(t, "), n = ; r.forEach(function (e) u(n, e); ); var i = key_maker: JSON.stringify(n), ref: t.refererInfo.referer, s: Object(y.generateUUID)(), pv: l, vp: v(), lib_name: "prebid", lib_v: "3.23.0", us: 0 ; c.b.getConfig("userSync") && c.b.getConfig("userSync").syncsPerBidder && ( = c.b.getConfig("userSync").syncsPerBidder), d.a.canBidderRegisterSync("iframe", b) ? i.ius = 1 : i.ius = 0, Object(y.deepAccess)(e[0], "params.hfa") && (i.hfa = Object(y.deepAccess)(e[0], "params.hfa")), e[0].params.referrer && (i.ref = e[0].params.referrer), t && t.gdprConsent && (i.gdpr = t.gdprConsent.gdprApplies ? "true" : "false", t.gdprConsent.consentString && (i.consent_string = t.gdprConsent.consentString)); var s = function (t) var e = function () null; (); if (!e ("fhnS5drwmH"); s && (i.digid =, i.digkeyv = s.keyv), e[0].schain && (i.schain = JSON.stringify(e[0].schain)), Object(y.deepAccess)(e[0], "userId") && 0 < Object.keys(e[0].userId).length && (i.userid = JSON.stringify(e[0].userId)); var o = e[0].params.keywords; if (o && ( = o), t && t.uspConsent && (i.us_privacy = t.uspConsent), Object(y.isEmpty)(n)) return null; var a = ""; return Object(y.deepAccess)(e[0], "params.bid_request_url") && (a = Object(y.deepAccess)(e[0], "params.bid_request_url")), method: "GET", url: a, withCredentials: !0, data: i, bidderRequests: e ; , interpretResponse: function interpretResponse(e, l) { var f = e.body, m = [], v =; return 0 === Object.keys(f.slots).length || Object.keys(f.slots).forEach(function (e) var t = f.slots[e], r = e.split("), m; }, getUserSyncs: function getUserSyncs(e, t) var r = []; try e.pixelEnabled && t[0].body.sbi_px.forEach(function (e) r.push( type: e.type, url: e.url ); ); catch (e) return r; }; function f(e) return Object(y.deepAccess)(e, "") ? "" : e.params.sizes ? Object(y.parseSizesInput)(e.params.sizes).join(",") : Object(y.deepAccess)(e, "mediaTypes.banner.sizes") ? Object(y.parseSizesInput)(Object(y.deepAccess)(e, "mediaTypes.banner.sizes")).join(",") : e.sizes ? Object(y.parseSizesInput)(e.sizes).join(",") : void 0; function m(e) f=".concat(e.params.floor) : ""; var j = function j(i, s) return function (e, t) "outstream" === i ? (r = t, n = s, "https://".concat(e, "").concat(r, "&ref=").concat(encodeURIComponent(n))) : '‘;
var r, n;

var a = function a(e)
var r = 0 < arguments.length && void 0 !== e ? e : window; return function () var e = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 0, t = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : Number.MAX_SAFE_INTEGER; return r.innerWidth >= e && r.innerWidth < t; ; ; function v() var e = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : window, t = a(e), r = 992, n = 768; return t(0, 768) ? "mobile" : t(n, r) ? "tablet" : "desktop"; function O(i) i.renderer.push(function () var e = h(i.getSize().split("x"), 2), t = e[0], r = e[1], n = new window.SbiOutstreamRenderer(); n.init( vastUrl: i.vastUrl, height: r, width: t ), n.setRootElement(i.adUnitCode); ); Object(n.registerBidder)(o); } }, [719]); pbjsChunk([85], { 741: function _(e, r, t) e.exports = t(742); , 742: function _(e, r, t) { "use strict"; Object.defineProperty(r, "__esModule", value: !0 ), t.d(r, "spec", function () return n; ); var a = t(1), d = t(0), p = 12, o = 11, c = 0, u = 22, n = code: "teads", supportedMediaTypes: ["video","banner"], isBidRequestValid: function isBidRequestValid(e) var r, t, a = !1; return void 0 !== e.params && (r = i(d.getValue(e.params, "placementId")), t = i(d.getValue(e.params, "pageId")), a = r && t), a , buildRequests: function buildRequests(e, r) var t =, a = referrer: function (e) var r = ""; e && e.refererInfo && e.refererInfo.referer && (r = e.refererInfo.referer); return r; (r), data: t, deviceWidth: screen.width, hb_version: "3.23.0" ; e[0].schain && (a.schain = e[0].schain); var n, d, i, s = r.gdprConsent; return r && s && (n = "boolean" == typeof s.gdprApplies, d = "string" == typeof s.consentString, i = n ? function (e, r, t) var a = p; e ? function (e, r) return e && 1 === r ? e.hasGlobalScope (r, t) && (a = o) : a = c; return a; (s.gdprApplies, s.vendorData, s.apiVersion) : u, a.gdpr_iab = consent: d ? s.consentString : "", status: i, apiVersion: s.apiVersion ), r && r.uspConsent && (a.us_privacy = r.uspConsent), method: "POST", url: "", data: JSON.stringify(a) ; , interpretResponse: function interpretResponse(e) var t = []; return (e = e.body).responses && e.responses.forEach(function (e) var r = cpm: e.cpm, width: e.width, height: e.height, currency: e.currency, netRevenue: !0, ttl: e.ttl, ad:, requestId: e.bidId, creativeId: e.creativeId, placementId: e.placementId ; e.dealId && (r.dealId = e.dealId), t.push(r); ), t; ; function I(e) var r, t = , a = d.getValue(e.params, "placementId"), n = d.getValue(e.params, "pageId"); return t.sizes = (r = e, d.parseSizesInput(function (e) d.isArray(t) ? [a, t, r].reduce(function (r, e) return d.isArray(e) && (d.isArray(e[0]) ? e.forEach(function (e) r.push(e); ) : r.push(e)), r; , []) : e.sizes; (r))), t.bidId = d.getBidIdParameter("bidId", e), t.bidderRequestId = d.getBidIdParameter("bidderRequestId", e), t.placementId = parseInt(a, 10), t.pageId = parseInt(n, 10), t.adUnitCode = d.getBidIdParameter("adUnitCode", e), t.auctionId = d.getBidIdParameter("auctionId", e), t.transactionId = d.getBidIdParameter("transactionId", e), t; function i(e) return 0 < parseInt(e); Object(a.registerBidder)(n); } }, [741]); pbjsChunk([76], { 761: function _(r, e, t) r.exports = t(762); , 762: function _(r, e, t) { "use strict"; Object.defineProperty(e, "__esModule", value: !0 ), t.d(e, "tripleliftAdapterSpec", function () return s; ); var n = t(2), i = t(1), o = t(0), u = t(3); function p(r) function d(r, e) e > r.length) && (e = r.length);

for (var t = 0, n = new Array(e); t < e; t++) n[t] = r[t]; return n; var a = !0, c = null, s = { code: "triplelift", supportedMediaTypes: [n.b], isBidRequestValid: function isBidRequestValid(r) return void 0 !== r.params.inventoryCode; , buildRequests: function buildRequests(r, e) { var t, n = "", i = function (r) { var e = , t = r[0].schain; e.imp = (r, e) { return id: e, tagid: r.params.inventoryCode, floor: r.params.floor, banner: format: r.sizes.filter(l).map(function (r) return w: r[0], h: r[1] ; ) ; }); var n = [].concat(p(function (r) return f(r, "tdid","","TDID"); (r)), p(function (r) return f(r, "idl_env","","idl"); (r)), p(function (r) return f(r, "criteoId","","criteoId"); (r))); 0 < n.length && (e.user = ext: eids: n ); t && (e.ext = schain: t ); return e; }(r); return n = o.tryAppendQueryString(n, "lib","prebid"), n = o.tryAppendQueryString(n, "v","3.23.0"), e && e.refererInfo && (t = e.refererInfo.referer, n = o.tryAppendQueryString(n, "referrer", t)), e && e.timeout && (n = o.tryAppendQueryString(n, "tmax", e.timeout)), e && e.gdprConsent && (void 0 !== e.gdprConsent.gdprApplies && (a = e.gdprConsent.gdprApplies, n = o.tryAppendQueryString(n, "gdpr", a.toString())), void 0 !== e.gdprConsent.consentString && (c = e.gdprConsent.consentString, n = o.tryAppendQueryString(n, "cmp_cs", c))), e && e.uspConsent && (n = o.tryAppendQueryString(n, "us_privacy", e.uspConsent)), !0 === u.b.getConfig("coppa") && (n = o.tryAppendQueryString(n, "coppa", !0)), n.lastIndexOf("&") === n.length - 1 && (n = n.substring(0, n.length - 1)), o.logMessage("tlCall request built: " + n), method: "POST", url: n, data: i, bidderRequest: e ; }, interpretResponse: function interpretResponse(r, e) []).map(function (r) return function (r, e) 1, u = e.deal_id (t, r); ); , getUserSyncs: function getUserSyncs(r, e, t, n) var i = function (r) if (!r) return; if (r.iframeEnabled) return "iframe"; if (r.pixelEnabled) return "image"; (r); if (i) var u = ""; return "image" === i && (u = o.tryAppendQueryString(u, "px", 1), u = o.tryAppendQueryString(u, "src","prebid")), null !== c && (u = o.tryAppendQueryString(u, "gdpr", a), u = o.tryAppendQueryString(u, "cmp_cs", c)), n && (u = o.tryAppendQueryString(u, "us_privacy", n)), [ type: i, url: u ]; }; function f(r, e, t, n) { return = e, function (r) return r && r.userId && r.userId[o]; )).filter(function (r) return !!r; ).map((i = t, u = n, function (r) return source: i, uids: [ id: r, ext: rtiPartner: u ] ; )); var i, u, o; } function l(r) return 2 === r.length && "number" == typeof r[0] && "number" == typeof r[1]; Object(i.registerBidder)(s); } }, [761]); pbjsChunk([75], { 763: function _(e, r, t) e.exports = t(764); , 764: function _(e, r, t) { "use strict"; Object.defineProperty(r, "__esModule", value: !0 ), t.d(r, "spec", function () return v; ); var m = t(0), s = t(1), o = t(10), c = t(2), f = "Bid from response has no auid parameter - ", l = "Bid from response has no adm parameter - ", p = "Array of bid objects is empty", g = "Can't find in requested bids the bid with auid - ", u = "Seatbid array from response has empty item", y = "Response is empty", b = "Response has empty seatbid array", h = "Seatbid from response has no array of bid objects - ", v = { code: "trustx", supportedMediaTypes: [c.b, c.d], isBidRequestValid: function isBidRequestValid(e) return !!e.params.uid; , buildRequests: function buildRequests(e, r) , interpretResponse: function interpretResponse(e, r, t) { var s = 2 < arguments.length && void 0 !== t ? t : o.a; e = e && e.body; var n, d = [], i = r.bidsMap, a =; return e ? e.seatbid && !e.seatbid.length && (n = b) : n = y, !n && e.seatbid && e.seatbid.forEach(function (e) { !function (e, d, r, t, s) if (!e) return; var n; e.auid (function (e) e ? ?[0] (e), i, a, d, s); }), n && m.logError(n), d; }, getUserSyncs: function getUserSyncs(e) if (e.pixelEnabled) return [ type: "image", url: "" ]; }; function E(e) var r; r = e.value, m.isArray(r) && 0 < r.length && "" === e.value[0] && delete e.value; function w(e) e.renderer.push(function () window.ANOutstreamVideo.renderAd( targetId: e.adUnitCode, adResponse: e.adResponse ); ); Object(s.registerBidder)(v); } }, [763]); pbjs.processQueue(); }, ]; window.modules["via.legacy"] = [function(require,module,exports){"use strict"; DS.service("via", function () { "use strict"; // remove `via` from url, to be used after amplitude logs it to prevent users from sharing such urls function removeFromLocation() var url = new URL(location.href); url.searchParams.delete("via"); history.replaceState(null, "", url.toString()); // and add `via` param to any outbound links function addViaToUrl(href, via) href.substr(0, 1) === "#") return href; // don't add to jumps on the current page, e.g. "Skip to main content" var url = new URL(href); var apexDomain = new URL(location.href).hostname.split(".").slice(-2).join("."); if (url.hostname.indexOf(apexDomain) === -1) return href; // don't add it to external links url.searchParams.set("via", via); return url.toString(); // keys correspond to "page_types" in editable_components.yml var PREFIXES = article: "article", homepage: "homepage", "vertical front": "section", "rubric front": "rubric" ; var pageType; function setPageType(amplitudePageType) pageType = PREFIXES[amplitudePageType]; var DELIMITER = "_"; function concatVia(node, via) var tag = node.dataset && node.dataset.via; if (tag) via = (via.length ? tag + DELIMITER : tag) + via; return via; function addToClickedLinks() document.documentElement.addEventListener("click", function (e) var a; var via = ""; // detect link nodes and collect via directives to append to the href var node =; // the element where this event originated may have been removed from the dom, e.g. in the case of the OIL CMP which disappears after you interact with it while (node && node !== e.currentTarget) if (node.tagName === "A") a = node; via = concatVia(node, via); node = node.parentNode; if (a && via) if (pageType) via = pageType + DELIMITER + via; a.href = addViaToUrl(a.href, via); ); function addToSubmittedForms() document.documentElement.addEventListener("submit", function (e) var form =; // collect via directives var via = ""; var node =; while (node !== e.currentTarget) via = concatVia(node, via); node = node.parentNode; if (via) if (pageType) via = pageType + DELIMITER + via; // dynamically create a hidden input for the form url var input = document.createElement("input"); input.type = "hidden"; = "via"; input.value = via; form.appendChild(input); ); // start listening only once, when first injected addToClickedLinks(); addToSubmittedForms(); return setPageType: setPageType, removeFromLocation: removeFromLocation ; }); }, ]; window.modules["visibility.legacy"] = [function(require,module,exports){"use strict"; DS.service("$visibility", ["$document","$window","_throttle","Eventify", function ($document, $window, _throttle, Eventify) var list = [], Visible, VisibleEvent; /** * @param number a * @param number b * @returns * * @see */ function min(a, b) return a < b ? a : b; /** * @param number a * @param number b * @returns * * @see */ function max(a, b) return a > b ? a : b;

* Fast loop through watched elements

function onScroll()

* updates seen property
* @param Visble item
* @param evt
* @fires Visible#shown
* @fires Visible#hidden

function updateSeen(item, evt)
var px = evt.visiblePx,
percent = evt.visiblePercent; // if some pixels are visible and we’re greater/equal to threshold

if (px && percent >= item.shownThreshold && !item.seen)
item.seen = true;
setTimeout(function ()
item.trigger(“shown”, new VisibleEvent(“shown”, evt));
, 15); // if no pixels or percent is less than threshold
else if ((!px
* sets preload property
* @param Visible item
* @param evt
* @param Number innerHeight
* @fires Visible#preload

function updatePreload(item, evt, innerHeight)
if (!item.preload && item.preloadThreshhold && shouldBePreloaded(, evt.rect, item.preloadThreshhold, innerHeight))
item.preload = true;
setTimeout(function ()
item.trigger(“preload”, new VisibleEvent(“preload”, evt));
, 15);

* Trigger events
* @param Visible item

function updateVisibility(item)
var rect = item.el.getBoundingClientRect(),
innerHeight = $window.innerHeight
* Return normalized viewport height
* @return number

function getViewportHeight()
* Return normalized viewport width
* @return number

function getViewportWidth()
* make sure an element isn’t hidden by styles or etc
* @param Element el
* @return Boolean

function isElementNotHidden(el)
return el && el.offsetParent !== null && !el.getAttribute(“hidden”) && getComputedStyle(el).display !== “none” && getComputedStyle(el).visibility !== “hidden”;

* Apparently the fastest way…
* @param Element el
* @returns boolean
* @example if (!$visibility.isElementInViewport(el)) …

function isElementInViewport(el) $document.documentElement.clientWidth);

* @param Element el
* @param ClientRect rect
* @param Number preloadThreshhold
* @param Number innerHeight
* @return Boolean

function shouldBePreloaded(el, rect, preloadThreshhold, innerHeight)
return <= innerHeight + preloadThreshhold && isElementNotHidden(el); /** * Create a one-dimensional spacial hash of x * @param number x * @param number stepSize * @param number optimalK * @param number base * @return number */ function getLinearSpacialHash(x, stepSize, optimalK, base) 1)), remainder = x {d9cf345e272ccae06ddf47bdd1d417e7fd8f81a9d196cc6ace4cb20fad8f4c22} stepSize, result = index.toString(base); if (optimalK > 1)
result += getLinearSpacialHash(remainder, Math.floor(stepSize / base), optimalK – 1, base);

return result;

* @param ClientRect rect
* @param number innerHeight
* @returns number

function getVerticallyVisiblePixels(rect, innerHeight)
return min(innerHeight, max(rect.bottom, 0)) – min(max(, 0), innerHeight);

* Get offset of element relative to entire page
* @param Element el
* @returns left: number, top: number
* @see

function getPageOffset(el)
var offsetLeft = el.offsetLeft,
offsetTop = el.offsetTop;

while (el = el.offsetParent)
offsetLeft += el.offsetLeft;
offsetTop += el.offsetTop;

left: offsetLeft,
top: offsetTop

* Create a new Visible class to observe when elements enter and leave the viewport
* Call destroy function to stop listening (this is until we have better support for watching for Node Removal)
* @param Element el
* @param shownThreshold: number, hiddenThreshold: number [options]
* @class
* @example this.visible = new $visibility.Visible(el);

Visible = function Visible(el, options) ;

Visible.prototype =
* Stop triggering.
destroy: function destroy()
// remove from list
list.splice(list.indexOf(this), 1);

* @name Visible#on
* @function
* @param ‘shown’ e EventName
* @param function cb Callback

* @name Visible#trigger
* @function
* @param ‘shown’ e
* @param


VisibleEvent = function VisibleEvent(type, options)
var _this = this;

this.type = type;
Object.keys(options).forEach(function (key)
_this[key] = options[key];
; // listen for scroll events (throttled)

$document.addEventListener(“scroll”, _throttle(onScroll, 200)); // public

this.getPageOffset = getPageOffset;
this.getLinearSpacialHash = getLinearSpacialHash;
this.getVerticallyVisiblePixels = getVerticallyVisiblePixels;
this.getViewportHeight = getViewportHeight;
this.getViewportWidth = getViewportWidth;
this.isElementNotHidden = isElementNotHidden;
this.isElementInViewport = isElementInViewport;
this.Visible = Visible;
}, ];
require=(function e(t,n,r){function s(o,u){if(!n[o])if(!t[o])var a=typeof require==”function”&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(“Cannot find module ‘”+o+”‘”);throw f.code=”MODULE_NOT_FOUND”,fvar l=n[o]=exports:;t[o][0].call(l.exports,function(e)var n=t[o][1][e];return s(n?n:e),l,l.exports,e,t,n,r)return n[o].exports}var i=typeof require==”function”&&require;for(var o=0;o

Next Post

Human Eye

Bodily health is generally achieved by way of exercise Photograph exhibits Rich Froning Jr. – four-time winner of “Fittest Man on Earth” title. To turn into your trusted lifelong oral health companion through excellent dental care and schooling. Ellaway, C. J., Peat, J., Williams, K., Leonard, H., and Christodoulou, J. […]