যদি কোনও এনজিএসসিআর পাথ 404 এ সমাধান করে তবে ডিফল্টে ফ্যালব্যাকের কোনও উপায় আছে কি?


129

আমি যে অ্যাপ্লিকেশনটি তৈরি করছি তার জন্য আমার ব্যবহারকারীর কাছে এই চিত্রটি লোড হওয়ার সম্ভাবনার আগে 4 টি তথ্য টুকরো সেট করা প্রয়োজন। এই চিত্রটি অ্যাপ্লিকেশনটির কেন্দ্র-অংশ, সুতরাং ভাঙা চিত্রের লিঙ্কটি পুরো জিনিসটি উদাস হয়ে যাওয়ার মতো দেখায়। আমি 404 এ অন্য একটি চিত্র স্থান পেতে চাই।

কোন ধারনা? আমি এটির জন্য একটি কাস্টম নির্দেশিকা লেখা এড়াতে চাই।

আমি অবাক হয়ে গিয়েছিলাম যে আমি কোনও অনুরূপ প্রশ্নটি খুঁজে পাই না, বিশেষত যখন ডক্সে প্রথম প্রশ্নটি একই হয়!

http://docs.angularjs.org/api/ng.directive:ngSrc


এটি প্রাসঙ্গিক হতে পারে: stackoverflow.com/q/13781685/1218080
হলোগ্রাফিক-নীতি

উত্তর:


252

কোনও চিত্র লোড করার সময় ত্রুটি এবং এসসিআর প্রতিস্থাপনের জন্য এটি দেখতে বেশ সহজ দিকনির্দেশনা। (Plunker)

এইচটিএমএল:

<img ng-src="smiley.png" err-src="http://google.com/favicon.ico" />

javascript:

var app = angular.module("MyApp", []);

app.directive('errSrc', function() {
  return {
    link: function(scope, element, attrs) {
      element.bind('error', function() {
        if (attrs.src != attrs.errSrc) {
          attrs.$set('src', attrs.errSrc);
        }
      });
    }
  }
});

আপনি যখন এনজিএসসিআর ফাঁকা থাকে ত্রুটি চিত্রটি প্রদর্শন করতে চান আপনি এটি (প্লঙ্কার) যুক্ত করতে পারেন :

attrs.$observe('ngSrc', function(value) {
  if (!value && attrs.errSrc) {
    attrs.$set('src', attrs.errSrc);
  }
});

সমস্যাটি হ'ল মানটি ফাঁকা থাকলে এনজিএসসিআরটি এসসিআর অ্যাট্রিবিউট আপডেট করে না।


ইউআরএলটি ভেঙে গেলে (404) ভাল কাজ করে তবে এটি যদি খালি স্ট্রিং হয় এনজি-এসসিআর চুপচাপ ত্রুটিটি গ্রাস করে।
স্টিফেন প্যাটেন

2
যদি কোনও খালি স্ট্রিংটি আপনার মডেলের জন্য বৈধ না হয়, তবে এটি তৈরি করুন যাতে আপনি এনজি-এসসিআরের সাথে আবশ্যকীয় যে অভিব্যক্তিটি খালি স্ট্রিংটি ফিরে না আসে।
জাস্টিন লোভারো

চিত্রটির srcজন্য গুণাবলীর ব্যবহারকে সমর্থন করতে স্ক্রিপ্ট আপডেট হয়েছে err-src: plnkr.co/edit/b05WtghBOHkxKdttZ8q5
রায়ান

@ জাস্টিনলভোরো আমি এটিকে কৌণিক দিকের একটি বাগ মনে করি এবং এটি রিপোর্ট করেছি reported সমস্যাটি হ'ল মানটি ফাঁকা থাকলে এনজিএসসিআরসিআরসিপি অ্যাট্রিবিউট সেট করে না। এটি আসলে কোনও সমস্যা হতে পারে যদি উদাহরণস্বরূপ আপনি কোনও ফোন প্রদর্শন করছেন এবং এজ্যাক্স সহ অন্য ফোনটি লোড করছেন যা কোনও চিত্রের ইউআরএল অনুপস্থিত। পুরানো ফোনের চিত্রটি প্রদর্শিত হতে থাকবে তবে আমার মনে হয় ত্রুটি বা স্থানধারক আরও উপযুক্ত হবে। হ্যাঁ আপনি এটি আপনার মডেলটিতে পরিচালনা করতে পারেন তবে পুরানো চিত্রটি রেখে যাওয়ার আচরণটি আমার মনে হয় ত্রুটি প্রদর্শন করার চেয়ে আরও বেশি ভুল।
জেসন গোয়ামাত

@ জেসনগোম্যাট, ভাঙা চিত্রটি পাঠ্যের সাথে প্রতিস্থাপন করতে আমি কী করব?
সাইমেগ

48

পার্টিতে কিছুটা দেরি, যদিও আমি তৈরি করছি এমন সিস্টেমে আমি কমবেশি একই সমস্যার সমাধান নিয়ে এসেছি।

যদিও আমার ধারণাটি ছিল imgবিশ্বব্যাপী প্রতিটি চিত্র ট্যাগ হ্যান্ডেল করা ।

আমি এখানে দেখানো HTMLমত অপ্রয়োজনীয় নির্দেশাবলী দিয়ে আমার মরিচ রাখতে চাইনি err-src। বেশিরভাগ ক্ষেত্রে, বিশেষত গতিশীল চিত্রগুলির সাথে, আপনি জানেন না যে এটি খুব দেরি না হওয়া অবধি নিখোঁজ রয়েছে। অফ-সুযোগে কোনও চিত্র নিখরচায় অতিরিক্ত নির্দেশিকা যুক্ত করা আমার কাছে ওভারকিল বলে মনে হচ্ছে।

পরিবর্তে, আমি বিদ্যমান imgট্যাগটি প্রসারিত করি - যা আসলেই কৌণিক নির্দেশাবলী all

সুতরাং - এই আমি নিয়ে এসেছি।

দ্রষ্টব্য : এটির জন্য সম্পূর্ণ জিকুয়ের লাইব্রেরি উপস্থিত থাকতে হবে এবং কেবল জিক্লাইট কৌনিক জাহাজের সাথে নয় কারণ আমরা ব্যবহার করছি.error()

আপনি এই প্লঙ্কার এটিকে ক্রিয়াতে দেখতে পাচ্ছেন

দিকনির্দেশকটি দেখতে বেশ সুন্দর দেখাচ্ছে:

app.directive('img', function () {
    return {
        restrict: 'E',        
        link: function (scope, element, attrs) {     
            // show an image-missing image
            element.error(function () {
                var w = element.width();
                var h = element.height();
                // using 20 here because it seems even a missing image will have ~18px width 
                // after this error function has been called
                if (w <= 20) { w = 100; }
                if (h <= 20) { h = 100; }
                var url = 'http://placehold.it/' + w + 'x' + h + '/cccccc/ffffff&text=Oh No!';
                element.prop('src', url);
                element.css('border', 'double 3px #cccccc');
            });
        }
    }
});

যখন কোনও ত্রুটি দেখা দেয় (যা হ'ল কারণ চিত্রটির অস্তিত্ব নেই বা অ্যাক্সেসযোগ্য নয় ইত্যাদি) আমরা ক্যাপচার করি এবং প্রতিক্রিয়া জানাই। আপনি চিত্রের আকারগুলিও পেতে চেষ্টা করতে পারেন - যদি তারা ছবিটিতে / স্টাইলটিতে প্রথম স্থানে উপস্থিত থাকে। যদি তা না হয় তবে নিজেকে একটি ডিফল্ট সেট করুন।

পরিবর্তে কোনও চিত্র দেখানোর জন্য এই উদাহরণটি প্লেসহোল্ড.আইটি ব্যবহার করছে।

এখন প্রতিটি চিত্র, ব্যবহার ব্যতিরেকেই srcবা ng-srcকোনও কিছুই লোড না হওয়ার ক্ষেত্রে নিজেই covered েকে ফেলেছে ...


2
খুব সুন্দর সমাধান! এই এক শীর্ষে ভোট দিন!
ম্যাথিজ

1
এটি বলতে বেশ সুন্দর। আমি আসলে কোনও চিত্রই দেখতে চাই না যদি এটির সমাধান না হয় তবে আমি ব্যবহার করেছি: এলিমেন্ট.এসএসএস ("প্রদর্শন", "কিছুই নয়"); এটি পুরোপুরি আড়াল করতে
পম্পে

1
চমৎকার :) বা আপনি এটিকে একে একে DOM থেকে পুরোপুরি সরিয়ে ফেলতে পারেন, عنصر.রেভ () দিয়ে; :)
ড্যারেন ওয়েনরাইট

দুর্দান্ত কাজ করে, ধন্যবাদ!
পরিবেশগত

আপনার সমাধানটি কিছুটা সম্পাদনা করেছেন, তাই পথ ফাঁকা থাকলে এটিও কাজ করে। stackoverflow.com/a/35884288/2014288
andrfas

21

লোডিং ত্রুটি বা খালি উত্সের স্ট্রিংয়ের উভয় ক্ষেত্রেই জেসন সমাধানটি প্রসারণ করতে আমরা কেবল একটি ঘড়ি যুক্ত করতে পারি।

এইচটিএমএল:

<img ng-src="smiley.png" err-src="http://google.com/favicon.ico" />

javascript:

var app = angular.module("MyApp", []);

app.directive('errSrc', function() {
  return {
    link: function(scope, element, attrs) {

      var watcher = scope.$watch(function() {
          return attrs['ngSrc'];
        }, function (value) {
          if (!value) {
            element.attr('src', attrs.errSrc);  
          }
      });

      element.bind('error', function() {
        element.attr('src', attrs.errSrc);
      });

      //unsubscribe on success
      element.bind('load', watcher);

    }
  }
});

2
চমৎকার কোড, তবে ng-ifটেমপ্লেটে (খালি এসআরসি স্ট্রিং) যা সহজে পরীক্ষা করা যায় তার জন্য একটি ঘড়ি যুক্ত করার জন্য একটি ওভারকিল বলে মনে হচ্ছে
অ্যালোনাইজার

দেখে মনে হচ্ছে আপনি কেবল নিজের নির্দেশের সাথে এনজিএসসিআর প্রতিস্থাপন করতে পারেন এবং যদি এটি চান তবে পৃথক ত্রুটি-নির্দেশনা রাখার পরিবর্তে এররসিআরসিআরকে ব্যবহার করার জন্য এটির ত্রুটির উপর ভিত্তি স্থাপন করতে পারেন। আপনি ব্যবহার করতে পারেন attrs.$observe('ngSrc', function(value) {...});, এনজিএসসিআর $ ওয়াচের পরিবর্তে অভ্যন্তরীণভাবে ব্যবহার করে
জেসন গোয়েমাট

ফাঁকাগুলির সাথে পুরো সমস্যাটি হ'ল এনজিএসসিআরটি যদি শূন্য হয় তবে এসআরসি বৈশিষ্ট্যটি আপডেট করে না, তাই আপনার যদি এনজিএসসিআর পরিবর্তে আপনার নিজস্ব নির্দেশিকা থাকে তবে এটি ফাঁকা চেকের প্রয়োজন হবে না।
জেসন গোমেট

1
@ পোকনো - আপনি ত্রুটি ফাংশনটির ভিতরে বর্তমান 'src' বৈশিষ্ট্যটি 'errSrc' এর মতো কিনা তা পরীক্ষা করতে পারেন।
ব্যবহারকারী 2899845

1
@ বিশাসাখায়ারগোলি - আনসাবস্ক্রাইব করার জন্য একটি কল যুক্ত করেছে, সুতরাং প্রাথমিক লোডিংয়ের পরে এটির কোনও প্রসেসিং ব্যয় হবে না
ব্যবহারকারীর 2899845

11
App.directive('checkImage', function ($q) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            attrs.$observe('ngSrc', function (ngSrc) {
                var deferred = $q.defer();
                var image = new Image();
                image.onerror = function () {
                    deferred.resolve(false);
                    element.attr('src', BASE_URL + '/assets/images/default_photo.png'); // set default image
                };
                image.onload = function () {
                    deferred.resolve(true);
                };
                image.src = ngSrc;
                return deferred.promise;
            });
        }
    };
});

এইচটিএমএলে:

<img class="img-circle" check-image ng-src="{{item.profileImg}}" />

আমি মনে করি এটি গ্রহণযোগ্য উত্তর হওয়া উচিত কারণ এটি jQuery ব্যবহার করে না এবং সমস্যার সমাধান করে
গ্রেগ্রা

10

যদি চিত্র 404 হয় বা নির্দেশের প্রয়োজন নেই এমন চিত্র যা শূন্য থাকে আপনি কেবল এনজি-এসসিআর ফিল্টারটি এর মতো ব্যবহার করতে পারেন :)

<img ng-src="{{ p.image || 'img/no-image.png' }}" />

2
না, যদি পি.আইমেজে কোনও এজেএক্স কলটিতে 404 ফেরত দেয় তবে এটি এটি 'সত্য' হিসাবে বিবেচনা করবে এবং দ্বিতীয় img / no-image.png এ যাবে না।
জেমস জেনেটস

2
@ জেমসজেটস - এটি মনে হয় না। এনজি-এসসিআর-এর এই ব্যবহারটি ঠিক যেমন দেখানো হয়েছে তেমন কাজ করে। এবং এটি এত সহজ।
শানেমগ্রে

@ শানভিগ ধন্যবাদ, এটি আকর্ষণীয় - আমি ভাবছি পিছনের প্রান্তটি কি আলাদা। আমি এক্সপ্রেসের সাথে নোড চালাচ্ছি, সম্ভবত এটি অন্যরকমভাবে পরিচালনা করে।
জেমস জেনেটস

2
@ জামেসজেটস - আমার আগের মন্তব্যের সংশোধন। মডেল দ্বারা বৈধ ইউআরআই ফেরত আসার সময় ওপি একটি সমাধান খুঁজছে, তবে এটি অনুসরণ করার পরে একটি 404। সেক্ষেত্রে এই সমাধানটি কাজ করে না, ফলস্বরূপ চিত্রটির ফলস্বরূপ। যদি কৌণিক চিত্রের মানটির জন্য কিছুই না দেয় তবে এটি সঠিকভাবে ফলব্যাকটি চয়ন করে।
শানেমগ্রে

আমি লারাভেল ব্যবহার করছি এবং 404, নাল বা ফাঁকা যদি হয় তবে এটি আমার জন্য উপযুক্ত। তবে এক্সপ্রেস 404 এর মতো কোডের প্রতিক্রিয়ার পরিবর্তে কোনও ধরণের ত্রুটি
ফেরায়

8

আমি এই জাতীয় কিছু ব্যবহার করি তবে এটি ধরে নেয় যে Team.Lgo বৈধ। "Team.logo" সেট না করা থাকলে বা খালি থাকলে এটি ডিফল্টরূপে বাধ্য করে।

<img ng-if="team.logo" ng-src="https://api.example.com/images/{{team.logo}}">
<img ng-hide="team.logo" ng-src="img/default.png">

2
এটি সঠিক, কারণ এটি "Team.logo" কে একটি স্ট্রিং (সত্য / মিথ্যা) হিসাবে মূল্যায়ন করে যখন এনজি-এসসিআর 40 {Team.logo} true সত্য হিসাবে দেখবে যদিও এটি 404 ফেরত দেয়
জেমস জেনেটস

2

এর জন্য আপনার কৌণিক প্রয়োজন হয় না, এমনকি সিএসএস বা জেএসও। আপনি যদি চান তবে আপনি এই উত্তরটিকে (লিঙ্কযুক্ত) এটিকে সরল, পছন্দ মতো বা অন্য কিছু করার জন্য একটি সহজ নির্দেশে মোড়ানো করতে পারেন তবে এটি একটি খুব সাধারণ প্রক্রিয়া ... এটি কেবল কোনও অবজেক্ট ট্যাগে মোড়ানো ...

শুধুমাত্র সিএসএস / এইচটিএমএল (জেএস ছাড়াই) ব্যবহার করে ভাঙা আইকনটি কীভাবে আড়াল করবেন?


1

কোনও নির্দিষ্ট কারণ আছে যা আপনি নিজের কোডে ফ্যালব্যাক চিত্রটি ঘোষণা করতে পারবেন না?

আমি যেমন বুঝতে পেরেছি, আপনার ইমেজ উত্সের জন্য আপনার দুটি সম্ভাব্য কেস রয়েছে:

  1. সঠিকভাবে তথ্যের টুকরো সেট করুন <4 = ফলব্যাক চিত্র।
  2. সঠিকভাবে তথ্যের টুকরোগুলি সেট করুন == 4 = উত্পন্ন URL।

আমি মনে করি এটি আপনার অ্যাপ্লিকেশন দ্বারা পরিচালনা করা উচিত - যদি সঠিক URL টি বর্তমানে নির্ধারণ করা না যায় তবে তার পরিবর্তে একটি লোডিং / ফ্যালব্যাক / প্লেসোল্ডার চিত্র URL টি পাস করুন।

যুক্তিটি হ'ল আপনার কখনও 'নিখোঁজ' চিত্র থাকবেন না, কারণ আপনি যে কোনও সময়ে স্পষ্টভাবে সঠিক URL টি প্রদর্শন করার জন্য ঘোষণা করেছেন।


দুঃখিত, আমার স্পষ্ট করা উচিত ছিল যে সমস্ত 4 টি মান সেট করা থাকলেও, ইউআরএল এখনও 404 করতে পারে (ব্যবহারকারী সেই পথে ফোল্ডার যুক্ত করতে পারে)) এর মধ্যে আমি একটি ফাংশন যুক্ত করেছি যা URL এর প্রতিক্রিয়া শিরোনামগুলি পরীক্ষা করে যখন সমস্ত মানগুলি নির্ধারণ করা হয়. এটি এখনও বিশেষ চিকিত্সা ছাড়াই এটি পরিচালনা করতে দুর্দান্ত লাগবে, আমি বাজি
ধরলাম

1
দুর্দান্ত, আপনার এটি উত্তর হিসাবে দেখাতে হবে এবং এটি ভবিষ্যতে অনুসন্ধানকারী যে কোনও ব্যক্তির কাছে গ্রহণযোগ্য হিসাবে চিহ্নিত করা উচিত।
অ্যালেক্স ওসোবার

1

আমি প্রস্তাব দিচ্ছি যে আপনি http://angular-ui.github.io/ তে পাওয়া যায়, আপনার সমস্যার সমাধানের জন্য 'যদি বিবৃতি' নির্দেশিকাতে কৌণিক UI ইউটিলগুলি ব্যবহার করতে পছন্দ করতে পারেন । আমি ঠিক এটি একই জিনিসটি করতে ব্যবহার করেছি।

এটি অনির্ধারিত, তবে আপনি যেমন কিছু করতে পারেন:

নিয়ামক কোড:

$scope.showImage = function () {
    if (value1 && value2 && value3 && value4) { 
        return true;
    } else {
        return false;
    }
};

(বা আরও সহজ)

$scope.showImage = function () {
    return value1 && value2 && value3 && value4;
};

এইচটিএমএল দেখুন: <img ui-if="showImage()" ng-src="images/{{data.value}}.jpg" />

বা এমনকি সহজ, আপনি কেবল একটি স্কোপ সম্পত্তি ব্যবহার করতে পারেন:

নিয়ামক কোড:

$scope.showImage = value1 && value2 && value3 && value4;

এইচটিএমএল দেখুন: <img ui-if="showImage" ng-src="images/{{data.value}}.jpg" />

কোনও স্থানধারক চিত্রের জন্য, কেবল একই অনুরূপ <img>ট্যাগ যুক্ত করুন তবে ui-ifএকটি বিবরণ দিয়ে আপনার প্যারামিটারটি প্রিপেন্ড করুন (! উদ্দীপনা ) চিহ্ন দিয়ে প্রিন্ট করুন, এবং হয় এনজিএসসিআরকে স্থানধারক চিত্রের পথ দেখান, বা কেবল srcসাধারণ ওএলএইচএমএল অনুযায়ী ট্যাগ ব্যবহার করুন ।

যেমন। <img ui-if="!showImage" src="images/placeholder.jpg" />

স্পষ্টতই, উপরের সমস্ত কোডের নমুনাগুলি ধরে নিচ্ছে যে মান 1, মান 2, মান 3 এবং মান 4 এর প্রতিটি সমান হবে null/ falseযখন আপনার 4 টি তথ্যের প্রতিটি তথ্য অসম্পূর্ণ থাকবে (এবং trueএটি সম্পূর্ণ হওয়ার পরে তার বুলিয়ান মানতেও )।

পুনশ্চ. অ্যাঙ্গুলারআইআই প্রকল্পটি সম্প্রতি সাব-প্রকল্পগুলিতে বিভক্ত হয়ে গেছে এবং এর জন্য ডকুমেন্টেশনটি ui-ifবর্তমানে অনুপস্থিত বলে মনে হচ্ছে (এটি সম্ভবত প্যাকেজে কোথাও রয়েছে)। যাইহোক, আপনি দেখতে পাচ্ছেন এটি ব্যবহার করা বেশ সোজা ular এবং এটি টিমের দিকেও দেখানোর জন্য আমি কৌনিক ইউআই প্রকল্পে একটি গিথুব 'ইস্যু' লগ ইন করেছি।

আপডেট: অ্যাঙ্গুলারআইআই প্রকল্প থেকে 'ইউআই-ইফ' অনুপস্থিত কারণ এটি মূল অ্যাংুলারজেএস কোডে সংহত হয়েছে! কেবলমাত্র v1.1.x হিসাবে, যা বর্তমানে 'অস্থির' হিসাবে চিহ্নিত হয়েছে।


ng-ifএটিকে মূল বিটিডব্লুতে পরিণত করেছে (1.1.5 হিসাবে যদি আমার ভুল না হয়)।
holographic- নীতি

1

দেশী জাভাস্ক্রিপ্ট ব্যবহার করে আমি এখানে এসেছি এমন একটি সমাধান। আমি ইমেজটি নষ্ট হয়ে গেছে কিনা তা যাচাই করে নিচ্ছি এবং কেবলমাত্র উত্স পরিবর্তন করার ক্ষেত্রে চিত্রটিতে একটি ক্লাস যুক্ত করুন।

আমি একটি কুয়োরা উত্তর থেকে আমার উত্তর অংশ পেয়েছিলাম http://www.quora.com/How-do-I-use-JavaScript-to-find-if-an-image-is-broken

app.directive('imageErrorDirective', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element[0].onerror = function () {
                element[0].className = element[0].className + " image-error";
                element[0].src = 'http://img3.wikia.nocookie.net/__cb20140329055736/pokemon/images/c/c9/702Dedenne.png';
            };
        }
    }
});

0

আমার নিজের সমাধান নিয়ে এসেছিল। এটি এসসিআর বা এনজিএসসিআর খালি থাকলে এবং img 404 ফেরত দিলে এটি উভয়ই চিত্র প্রতিস্থাপন করে।

(@ ড্যারেন সলিউশনের কাঁটাচামচ)

directive('img', function () {
return {
    restrict: 'E',        
    link: function (scope, element, attrs) {   
        if((('ngSrc' in attrs) && typeof(attrs['ngSrc'])==='undefined') || (('src' in attrs) && typeof(attrs['src'])==='undefined')) {
            (function () {
                replaceImg();
            })();
        };
        element.error(function () {
            replaceImg();
        });

        function replaceImg() {
            var w = element.width();
            var h = element.height();
            // using 20 here because it seems even a missing image will have ~18px width 
            // after this error function has been called
            if (w <= 20) { w = 100; }
            if (h <= 20) { h = 100; }
            var url = 'http://placehold.it/' + w + 'x' + h + '/cccccc/ffffff&text=No image';
            element.prop('src', url);
        }
    }
}
});

0

এটি কেবলমাত্র দু'বার লুপ করার অনুমতি দেবে, এনজি-এসসিআর উপস্থিত রয়েছে কিনা অন্য কোনও ত্রুটি-ত্রুটি ব্যবহার করবে না তা পরীক্ষা করে এটি লুপিং অব্যাহত রাখতে বাধা দেয়।

(function () {
    'use strict';
    angular.module('pilierApp').directive('errSrc', errSrc);

    function errSrc() {
        return {
            link: function(scope, element, attrs) {
             element.error(function () {
                // to prevent looping error check if src == ngSrc
                if (element.prop('src')==attrs.ngSrc){
                     //stop loop here
                     element.prop('src', attrs.errSrc);
                }              
            });
            }
        }
    }
})();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.