+ value = '';
+ needRemove = true;
+ } else if (type === 'number') {
+ // e.g.
![]()
+ // the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
+ value = 0;
+ needRemove = true;
+ }
+ }
+ // some properties perform value validation and throw,
+ // some properties has getter, no setter, will error in 'use strict'
+ // eg.
+ try {
+ el[key] = value;
+ } catch (e) {
+ _runtimeCore.warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` + `value ${value} is invalid.`, e);
+ }
+ needRemove && el.removeAttribute(key);
+}
+// Async edge case fix requires storing an event listener's attach timestamp.
+const [_getNow, skipTimestampCheck] = /*#__PURE__*/ (()=>{
+ let _getNow1 = Date.now;
+ let skipTimestampCheck1 = false;
+ if (typeof window !== 'undefined') {
+ // Determine what event timestamp the browser is using. Annoyingly, the
+ // timestamp can either be hi-res (relative to page load) or low-res
+ // (relative to UNIX epoch), so in order to compare time we have to use the
+ // same timestamp type when saving the flush timestamp.
+ if (Date.now() > document.createEvent('Event').timeStamp) // if the low-res timestamp which is bigger than the event timestamp
+ // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
+ // and we need to use the hi-res version for event listeners as well.
+ _getNow1 = ()=>performance.now()
+ ;
+ // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
+ // and does not fire microtasks in between event propagation, so safe to exclude.
+ const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
+ skipTimestampCheck1 = !!(ffMatch && Number(ffMatch[1]) <= 53);
+ }
+ return [
+ _getNow1,
+ skipTimestampCheck1
+ ];
+})();
+// To avoid the overhead of repeatedly calling performance.now(), we cache
+// and use the same timestamp for all event listeners attached in the same tick.
+let cachedNow = 0;
+const p = /*#__PURE__*/ Promise.resolve();
+const reset = ()=>{
+ cachedNow = 0;
+};
+const getNow = ()=>cachedNow || (p.then(reset), cachedNow = _getNow())
+;
+function addEventListener(el, event, handler, options) {
+ el.addEventListener(event, handler, options);
+}
+function removeEventListener(el, event, handler, options) {
+ el.removeEventListener(event, handler, options);
+}
+function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
+ // vei = vue event invokers
+ const invokers = el._vei || (el._vei = {});
+ const existingInvoker = invokers[rawName];
+ if (nextValue && existingInvoker) // patch
+ existingInvoker.value = nextValue;
+ else {
+ const [name, options] = parseName(rawName);
+ if (nextValue) {
+ // add
+ const invoker = invokers[rawName] = createInvoker(nextValue, instance);
+ addEventListener(el, name, invoker, options);
+ } else if (existingInvoker) {
+ // remove
+ removeEventListener(el, name, existingInvoker, options);
+ invokers[rawName] = undefined;
+ }
+ }
+}
+const optionsModifierRE = /(?:Once|Passive|Capture)$/;
+function parseName(name) {
+ let options;
+ if (optionsModifierRE.test(name)) {
+ options = {};
+ let m;
+ while(m = name.match(optionsModifierRE)){
+ name = name.slice(0, name.length - m[0].length);
+ options[m[0].toLowerCase()] = true;
+ }
+ }
+ return [
+ _shared.hyphenate(name.slice(2)),
+ options
+ ];
+}
+function createInvoker(initialValue, instance) {
+ const invoker = (e)=>{
+ // async edge case #6566: inner click event triggers patch, event handler
+ // attached to outer element during patch, and triggered again. This
+ // happens because browsers fire microtask ticks between event propagation.
+ // the solution is simple: we save the timestamp when a handler is attached,
+ // and the handler would only fire if the event passed to it was fired
+ // AFTER it was attached.
+ const timeStamp = e.timeStamp || _getNow();
+ if (skipTimestampCheck || timeStamp >= invoker.attached - 1) _runtimeCore.callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */ , [
+ e
+ ]);
+ };
+ invoker.value = initialValue;
+ invoker.attached = getNow();
+ return invoker;
+}
+function patchStopImmediatePropagation(e1, value) {
+ if (_shared.isArray(value)) {
+ const originalStop = e1.stopImmediatePropagation;
+ e1.stopImmediatePropagation = ()=>{
+ originalStop.call(e1);
+ e1._stopped = true;
+ };
+ return value.map((fn)=>(e)=>!e._stopped && fn && fn(e)
+ );
+ } else return value;
+}
+const nativeOnRE = /^on[a-z]/;
+const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren)=>{
+ if (key === 'class') patchClass(el, nextValue, isSVG);
+ else if (key === 'style') patchStyle(el, prevValue, nextValue);
+ else if (_shared.isOn(key)) // ignore v-model listeners
+ {
+ if (!_shared.isModelListener(key)) patchEvent(el, key, prevValue, nextValue, parentComponent);
+ } else if (key[0] === '.' ? (key = key.slice(1), true) : key[0] === '^' ? (key = key.slice(1), false) : shouldSetAsProp(el, key, nextValue, isSVG)) patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
+ else {
+ // special case for
with
+ // :true-value & :false-value
+ // store value as dom properties since non-string values will be
+ // stringified.
+ if (key === 'true-value') el._trueValue = nextValue;
+ else if (key === 'false-value') el._falseValue = nextValue;
+ patchAttr(el, key, nextValue, isSVG);
+ }
+};
+function shouldSetAsProp(el, key, value, isSVG) {
+ if (isSVG) {
+ // most keys must be set as attribute on svg elements to work
+ // ...except innerHTML & textContent
+ if (key === 'innerHTML' || key === 'textContent') return true;
+ // or native onclick with function values
+ if (key in el && nativeOnRE.test(key) && _shared.isFunction(value)) return true;
+ return false;
+ }
+ // these are enumerated attrs, however their corresponding DOM properties
+ // are actually booleans - this leads to setting it with a string "false"
+ // value leading it to be coerced to `true`, so we need to always treat
+ // them as attributes.
+ // Note that `contentEditable` doesn't have this problem: its DOM
+ // property is also enumerated string values.
+ if (key === 'spellcheck' || key === 'draggable' || key === 'translate') return false;
+ // #1787, #2840 form property on form elements is readonly and must be set as
+ // attribute.
+ if (key === 'form') return false;
+ // #1526
must be set as attribute
+ if (key === 'list' && el.tagName === 'INPUT') return false;
+ // #2766