/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["redirect"],{ef3c:function(e,t,a){"use strict";a.r(t);a("a481");var r=a("d225"),c=a("b0b4"),n=a("308d"),u=a("6bb5"),b=a("4e2b"),i=a("9ab4"),o=a("60a3"),p=function(e){function t(){return Object(r["a"])(this,t),Object(n["a"])(this,Object(u["a"])(t).apply(this,arguments))}return Object(b["a"])(t,e),Object(c["a"])(t,[{key:"created",value:function(){var e=this.$route,t=e.params,a=e.query,r=t.path;this.$router.replace({path:"/"+r,query:a})}},{key:"render",value:function(){}}]),t}(o["c"]);p=i["a"]([Object(o["a"])({name:"Redirect"})],p);var s,l,d=p,h=d,f=a("2877"),j=Object(f["a"])(h,s,l,!1,null,null,null);t["default"]=j.exports}}]);