Commit 4c399227 authored by berge's avatar berge
Browse files

Initial TT source code

parents
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
/*
 * ----------------------------------------------------------------------------
 *  (C) Copyright Testing Technologies, 2013-2014.  All Rights Reserved.
 *
 *  All copies of this program, whether in whole or in part, and whether
 *  modified or not, must display this and all other embedded copyright
 *  and ownership notices in full.
 *
 *  See the file COPYRIGHT for details of redistribution and use.
 *
 *  You should have received a copy of the COPYRIGHT file along with
 *  this file; if not, write to the Testing Technologies,
 *  Michaelkirchstr. 17/18, 10179 Berlin, Germany.
 *
 *  TESTING TECHNOLOGIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 *  SOFTWARE. IN NO EVENT SHALL TESTING TECHNOLOGIES BE LIABLE FOR ANY
 *  SPECIAL, DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 *  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 *  THIS SOFTWARE.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
 *  EITHER EXPRESSED OR IMPLIED, INCLUDING ANY KIND OF IMPLIED OR
 *  EXPRESSED WARRANTY OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

module AMQPort_Types {
    type record of charstring CharstringList;
    type enumerated AMQPPort_Mode {
        Consumer,
        Producer
    } 
}
 No newline at end of file
+186 −0
Original line number Diff line number Diff line
/*
 * ----------------------------------------------------------------------------
 *  (C) Copyright Testing Technologies, 2013-2014.  All Rights Reserved.
 *
 *  All copies of this program, whether in whole or in part, and whether
 *  modified or not, must display this and all other embedded copyright
 *  and ownership notices in full.
 *
 *  See the file COPYRIGHT for details of redistribution and use.
 *
 *  You should have received a copy of the COPYRIGHT file along with
 *  this file; if not, write to the Testing Technologies,
 *  Michaelkirchstr. 17/18, 10179 Berlin, Germany.
 *
 *  TESTING TECHNOLOGIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 *  SOFTWARE. IN NO EVENT SHALL TESTING TECHNOLOGIES BE LIABLE FOR ANY
 *  SPECIAL, DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 *  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 *  THIS SOFTWARE.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
 *  EITHER EXPRESSED OR IMPLIED, INCLUDING ANY KIND OF IMPLIED OR
 *  EXPRESSED WARRANTY OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

module Commands {
  import from TypesAndConst all;

  type record SetConfigCmd {
    integer worker,
    ConfigParameters parameters
  } with {
    variant "set_config";
    variant (worker) "worker";
  }
  
  template SetConfigCmd SetConfig (
    integer worker,
    ConfigParameters parameters
  ) := {
    worker := worker,
    parameters := parameters
  }

  template SetConfigCmd SetInbandModelState (
    integer worker,
    ModemStateType state
  ) := {
    worker := worker,
    parameters := {
      inbandState := state
    }
  }

  template SetConfigCmd SetAutomaticAlAck (
    integer worker,
    boolean automaticAlAck := true,
    AckValueType alAckValue := 0
  ) := {
    worker := worker,
    parameters := {
      automaticAlAck := automaticAlAck,
      alAckValue := alAckValue
    }
  }

  type record CallAcceptCmd {
    integer worker,
    CallRefType callRef
  } with {
    variant "call_accept";
    variant (worker) "worker";
    variant (callRef) "call-ref";
  }
  
  template CallAcceptCmd CallAccept (
    integer worker
  ) := {
    worker := worker,
    callRef := EXTERNAL
  }

  type record CallHangUpCmd {
    integer worker
  } with {
    variant "call_hang_up";
    variant (worker) "worker";
  }
  
  template CallHangUpCmd CallHangUpC (
    integer worker
  ) := {
      worker := worker
  }

  type record CallRejectBusyCmd {
    integer worker,
    CallRefType callRef
  } with {
    variant "call_reject_busy";
    variant (worker) "worker";
    variant (callRef) "call-ref";
  }

  template CallRejectBusyCmd CallRejectBusy (
    template(present) integer worker,
    template(present) CallRefType callRef := EXTERNAL
  ) := {
    worker := worker,
    callRef := callRef
  }

  type record CallCreateCmd {
    integer worker,
    charstring to_,
    CallRefType callRef
  } with {
    variant "call_create"
    variant (worker) "worker";
    variant (to_) "to";
    variant (callRef) "call-ref";
  }
  
  template CallCreateCmd CallCreate (
    template(present) integer worker,
    template(present) charstring to_,
    template(present) CallRefType callRef := EXTERNAL
  ) := {
    worker := worker,
    to_ := to_,
    callRef := callRef
  }

  type record CallCancelCmd {
    integer worker,
    CallRefType callRef
  } with {
    variant "call_cancel"
    variant (worker) "worker";
    variant (callRef) "call-ref";
  }

  template CallCancelCmd CallCancel (
    template(present) integer worker,
    template(present) CallRefType callRef := EXTERNAL
  ) := {
    worker := worker,
    callRef := callRef
  }

  type record InbandRequestMsdCmd {
    integer worker
  } with {
    variant "inband_request_msd"
  }
  
  template InbandRequestMsdCmd InbandRequestMsd (
    template(present) integer worker
  ) := {
    worker := worker
  }

  type record InbandSendAlAckCmd {
    integer worker,
    AckValueType val
  } with {
    variant "inband_send_al_ack";
    variant (worker) "worker";
    variant (val) "value";
  }

  template InbandSendAlAckCmd InbandSendAlAck (
    integer worker,
    AckValueType val := POSITIVE_AL_ACK
  ) := {
    worker := worker,
    val := val
  }
} with {
  encode "SimulatorInterface";
}
 No newline at end of file
+59 −0
Original line number Diff line number Diff line
/*
 * ----------------------------------------------------------------------------
 *  (C) Copyright Testing Technologies, 2013-2014.  All Rights Reserved.
 *
 *  All copies of this program, whether in whole or in part, and whether
 *  modified or not, must display this and all other embedded copyright
 *  and ownership notices in full.
 *
 *  See the file COPYRIGHT for details of redistribution and use.
 *
 *  You should have received a copy of the COPYRIGHT file along with
 *  this file; if not, write to the Testing Technologies,
 *  Michaelkirchstr. 17/18, 10179 Berlin, Germany.
 *
 *  TESTING TECHNOLOGIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 *  SOFTWARE. IN NO EVENT SHALL TESTING TECHNOLOGIES BE LIABLE FOR ANY
 *  SPECIAL, DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 *  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 *  THIS SOFTWARE.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
 *  EITHER EXPRESSED OR IMPLIED, INCLUDING ANY KIND OF IMPLIED OR
 *  EXPRESSED WARRANTY OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

module Common {
  import from TypesAndConst all;

  /** @desc  IVS' Call Clear-down Fallback Timer */
  modulepar float T2_TIMER := 3600.0;

  /** @desc IVS INITIATION signal duration */
  modulepar float T3_TIMER := 2.0;
  
  /** @desc PSAP wait for INITIATION signal period */
  modulepar float T4_TIMER := 5.0;
  
  /** @desc IVS wait for SEND MSD period */
  modulepar float T5_TIMER := 5.0;
  
  /** @desc IVS wait for AL-ACK period */
  modulepar float T6_TIMER := 5.0;
  
  /** @desc IVS  MSD  maximum transmission time */
  modulepar float T7_TIMER := 20.0;
  
  /** @desc PSAP MSD maximum reception time */
  modulepar float T8_TIMER := 20.0;

  /** @desc Generic timeout for expected events */
  modulepar float TIMEOUT := 30.0;

  template ECallMessageUnion ANY_DECODED_ECALL := { decoded := ? }
}
 No newline at end of file
+560 −0
Original line number Diff line number Diff line
/*
 * ----------------------------------------------------------------------------
 *  (C) Copyright Testing Technologies, 2013-2014.  All Rights Reserved.
 *
 *  All copies of this program, whether in whole or in part, and whether
 *  modified or not, must display this and all other embedded copyright
 *  and ownership notices in full.
 *
 *  See the file COPYRIGHT for details of redistribution and use.
 *
 *  You should have received a copy of the COPYRIGHT file along with
 *  this file; if not, write to the Testing Technologies,
 *  Michaelkirchstr. 17/18, 10179 Berlin, Germany.
 *
 *  TESTING TECHNOLOGIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 *  SOFTWARE. IN NO EVENT SHALL TESTING TECHNOLOGIES BE LIABLE FOR ANY
 *  SPECIAL, DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 *  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 *  THIS SOFTWARE.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
 *  EITHER EXPRESSED OR IMPLIED, INCLUDING ANY KIND OF IMPLIED OR
 *  EXPRESSED WARRANTY OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

module Events {
  import from TypesAndConst all;

  type record ConfigChangedEvent {
    integer worker,
    charstring time,
    ConfigParameters parameters
  } with {
    variant "event;config_changed";
    variant (worker) "worker";
    variant (time) "time";
  }

  /**
   * @desc Configuration template for simulator IVS mode
   */
  template ConfigChangedEvent IVSConfigChanged (
    template(present) integer worker,
    template(present) charstring time,
    template(present) ConfigParameters parameters
  ) := {
    worker := worker,
    time :=  time,
    parameters := {
      mode := parameters.mode,
      t3Timer := parameters.t3Timer,
      t4Timer := *,
      t5Timer := parameters.t5Timer,
      t6Timer := parameters.t6Timer,
      t7Timer := parameters.t7Timer,
      t8Timer := *,
      sendNecDisabler := *,
      numberOfAlAcks := *,
      numberOfLlAcks := *,
      eCallMessage := parameters.eCallMessage,
      alAckValue := *,
      automaticAlAck := *,
      inbandState := parameters.inbandState,
      inbandControl := parameters.inbandControl,
      inbandDirection := parameters.inbandDirection,
      internalSubscriber := parameters.internalSubscriber,
      ignoreAlClearDown := parameters.ignoreAlClearDown,
      simulateCrcError := parameters.simulateCrcError,
      ignoreSendSignal := *
    }
  }

  /**
   * @desc Configuration template for simulator PSAP mode
   */
  template ConfigChangedEvent PSAPConfigChanged (
    template(present) integer worker,
    template(present) charstring time,
    template(present) ConfigParameters parameters
  ) := {
    worker := worker,
    time :=  time,
    parameters := {
      mode := parameters.mode,
      t3Timer := *,
      t4Timer := parameters.t4Timer,
      t5Timer := *,
      t6Timer := parameters.t6Timer,
      t7Timer := *,
      t8Timer := parameters.t8Timer,
      sendNecDisabler := parameters.sendNecDisabler,
      numberOfAlAcks := parameters.numberOfAlAcks,
      numberOfLlAcks := parameters.numberOfLlAcks,
      eCallMessage := *,
      alAckValue := parameters.alAckValue,
      automaticAlAck := parameters.automaticAlAck,
      inbandState := parameters.inbandState,
      inbandControl := parameters.inbandControl,
      inbandDirection := parameters.inbandDirection,
      internalSubscriber := parameters.internalSubscriber,
      ignoreAlClearDown := *,
      simulateCrcError := parameters.simulateCrcError,
      ignoreSendSignal := parameters.ignoreSendSignal
    }
  }
  
  type record InbandMsdReceivedEvent {
    integer worker,
    charstring time,
    ECallMessageUnion eCallMessage
  } with {
    variant "event;inband_msd_received";
    variant (worker) "worker";
    variant (time) "time";
    variant (eCallMessage) "msd";
    encode (eCallMessage) "ECallMessageUnion";
  }
    
  template InbandMsdReceivedEvent InbandMsdReceived (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) ECallMessageUnion eCallMessage := ?
  ) := {
    worker := worker,
    time :=  time,
    eCallMessage := toTemplate(eCallMessage)
  }
  
  type record InbandLlAckSentEvent {
    integer worker,
    charstring time,
    AckNumberType count
  } with {
    variant "event;inband_ll_ack_sent";
    variant (worker) "worker";
    variant (time) "time";
    variant (count) "count";
  }
  
  template InbandLlAckSentEvent InbandLlAckSent (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) AckNumberType count := ?
  ) := {
    worker := worker,
    time := time,
    count := count
  }
  
  type record InbandLlAckReceivedEvent {
    integer worker,
    charstring time,
    AckNumberType count,
    boolean reliable
  } with {
    variant "event;inband_ll_ack_received";
    variant (worker) "worker";
    variant (time) "time";
    variant (count) "count";
    variant (reliable) "reliable";
  }
  
  template InbandLlAckReceivedEvent InbandLlAckReceived (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) AckNumberType count := ?,
    template(present) boolean reliable := ?
  ) := {
    worker := worker,
    time := time,
    count := count,
    reliable := reliable
  }

  type record InbandAlAckSentEvent {
    integer worker,
    charstring time,
    AckNumberType count,
    AckValueType val
  } with {
    variant "event;inband_al_ack_sent";
    variant (worker) "worker";
    variant (time) "time";
    variant (count) "count";
    variant (val) "value";
  }
  
  template InbandAlAckSentEvent InbandAlAckSent (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) AckNumberType count := ?,
    template(present) AckValueType val := ?
  ) := {
    worker := worker,
    time := time,
    count := count,
    val :=  val
  }
  
  type record InbandAlAckReceivedEvent {
    integer worker,
    charstring time,
    AckNumberType count,
    AckValueType val,
    boolean reliable
  } with {
    variant "event;inband_al_ack_received";
    variant (worker) "worker";
    variant (time) "time";
    variant (count) "count";
    variant (val) "value";
    variant (reliable) "reliable";
  }
  
  template InbandAlAckReceivedEvent InbandAlAckReceived (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) AckNumberType count := ?,
    template(present) AckValueType val := ?,
    template(present) boolean reliable := ?
  ) := {
    worker := worker,
    time := time,
    count := count,
    val :=  val,
    reliable := reliable
  }
  
  type record InbandStateChangedEvent {
    integer worker,
    charstring time,
    ModemStateType fromState,
    ModemStateType toState
  } with {
    variant "event;inband_state_changed";
    variant (worker) "worker";
    variant (time) "time";
    variant (fromState) "from-state";
    variant (toState) "to-state";
  }

  template InbandStateChangedEvent InbandStateChanged (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) ModemStateType fromState := ?,
    template(present) ModemStateType toState := ?
  ) := {
    worker := worker,
    time := time,
    fromState := fromState,
    toState := toState
  }
  
  type record InbandSendSignalReceivedEvent {
    integer worker,
    charstring time
  } with {
    variant "event;inband_send_signal_received";
    variant (worker) "worker";
    variant (time) "time";
  }
  
  template InbandSendSignalReceivedEvent InbandSendSignalReceived (
    template(present) integer worker,
    template(present) charstring time := ?
  ) := {
    worker := worker,
    time := time
  }
  
  type record InbandNackSentEvent {
    integer worker,
    charstring time,
    PositiveInteger count
  } with {
    variant "event;inband_nack_sent";
    variant (worker) "worker";
    variant (time) "time";
    variant (count) "count";
  }

  template InbandNackSentEvent InbandNackSent (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) PositiveInteger count := ?
  ) := {
    worker := worker,
    time := time,
    count := count
  }

  type record InbandNackReceivedEvent {
    integer worker,
    charstring time,
    PositiveInteger count
  } with {
    variant "event;inband_nack_received";
    variant (worker) "worker";
    variant (time) "time";
    variant (count) "count";
  }

  template InbandNackReceivedEvent InbandNackReceived (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) PositiveInteger count := ?
  ) := {
    worker := worker,
    time := time,
    count := count
  }

  type record CallCanceledEvent {
    integer worker,
    charstring time,
    CallRefType callRef
  } with {
    variant "event;call_cancelled";
    variant (worker) "worker";
    variant (time) "time";
    variant (callRef) "call-ref";
  }

  template CallCanceledEvent CallCanceled (
     template(present) integer worker,
     template(present) charstring time := ?,
     template(present) CallRefType callRef := EXTERNAL
   ) := {
     worker := worker,
     time := time,
     callRef := callRef
   }

  type record CallIncomingEvent {
    integer worker,
    charstring time,
    TelephhoneNumber from_,
    TelephhoneNumber to_,
    CallRefType callRef
  } with {
    variant "event;call_incoming";
    variant (worker) "worker";
    variant (time) "time";
    variant (from_) "from";
    variant (to_) "to";
    variant (callRef) "call-ref";
  }
  
  template CallIncomingEvent CallIncoming (
    template(present) integer worker,
    template(present) charstring time,
    template(present) TelephhoneNumber from_,
    template(present) TelephhoneNumber to_,
    template(present) CallRefType callRef
  ) := {
    worker := worker,
    time := time,
    from_ := from_,
    to_ := to_,
    callRef := callRef
  }
  
  type record CallOutgoingEvent {
    integer worker,
    charstring time,
    TelephhoneNumber from_,
    TelephhoneNumber to_,
    CallRefType callRef
  } with {
    variant "event;call_outgoing";
    variant (worker) "worker";
    variant (time) "time";
    variant (from_) "from";
    variant (to_) "to";
    variant (callRef) "call-ref";
  }

  template CallOutgoingEvent CallOutgoing (
    template(present) integer worker,
    template(present) charstring time,
    template(present) TelephhoneNumber from_,
    template(present) TelephhoneNumber to_,
    template(present) CallRefType callRef
  ) := {
    worker := worker,
    time := time,
    from_ := from_,
    to_ := to_,
    callRef := callRef
  }

  type record CallEstablishedEvent {
    integer worker,
    charstring time,
    CallRefType callRef
  } with {
    variant "event;call_established";
    variant (worker) "worker";
    variant (time) "time";
    variant (callRef) "call-ref";
  }

  template CallEstablishedEvent CallEstablished (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) CallRefType callRef := EXTERNAL
  ) := {
    worker := worker,
    time := time,
    callRef := callRef
  }
  
  type record CallRejectedEvent {
    integer worker,
    charstring time,
    CallRefType callRef
  } with {
    variant "event;call_rejected";
    variant (worker) "worker";
    variant (time) "time";
    variant (callRef) "call-ref";
  }

  template CallRejectedEvent CallRejected (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) CallRefType callRef := EXTERNAL
  ) := {
    worker := worker,
    time := time,
    callRef := callRef
  }
  
  type record CallHangUpEvent {
    integer worker,
    charstring time,
    CallRefType callRef
  } with {
    variant "event;call_hang_up";
    variant (worker) "worker";
    variant (time) "time";
    variant (callRef) "call-ref";
  }

  template CallHangUpEvent CallHangUp (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) CallRefType callRef := ?
  ) := {
    worker := worker,
    time := time,
    callRef := callRef
  }
  
  type record CallAbortedEvent {
    integer worker,
    charstring time,
    CallRefType callRef,
    charstring reason
  } with {
    variant "event;call_aborted";
    variant (worker) "worker";
    variant (time) "time";
    variant (callRef) "call-ref";
    variant (reason) "reason";
  }

  template CallAbortedEvent CallAborted (
    template(present) integer worker,
    template(present) charstring time,
    template(present) CallRefType callRef,
    template(present) charstring reason
  ) := {
    worker := worker,
    time := time,
    callRef := callRef,
    reason := reason
  }

  type record CallVoiceConnectionEstablishedEvent {
    integer worker,
    charstring time
  } with {
    variant "event;call_voice_connection_established";
    variant (worker) "worker";
    variant (time) "time";
  }
  
  template CallVoiceConnectionEstablishedEvent CallVoiceConnectionEstablished (
    template(present) integer worker,
    template(present) charstring time := ?
  ) :={
    worker := worker,
    time := time
  }
  
  type record InbandStartSignalReceivedEvent {
    integer worker,
    charstring time,
    PositiveInteger count,
    boolean reliable
  } with {
    variant "event;inband_start_signal_received";
    variant (worker) "worker";
    variant (time) "time";
    variant (count) "count";
    variant (reliable) "reliable";
  }

  template InbandStartSignalReceivedEvent InbandStartSignalReceived (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) PositiveInteger count := ?,
    template(present) boolean reliable := ?
  ) := {
    worker := worker,
    time := time,
    count := count,
    reliable := reliable
  }

  type record TimerExpiredEvent {
    integer worker,
    charstring time,
    charstring name,
    float val
  } with {
    variant "event;timer_expired";
    variant (worker) "worker";
    variant (time) "time";
    variant (name) "name";
    variant (val) "value";
  }

  template TimerExpiredEvent TimerExpired (
    template(present) integer worker,
    template(present) charstring time := ?,
    template(present) charstring name := ?,
    template(present) float val := ?
  ) := {
    worker := worker,
    time := time,
    name := name,
    val := val
  }

  template TimerExpiredEvent T7Expired(
    template(present) integer worker
  ) := TimerExpired(worker, ?, "t7", ?);

  template TimerExpiredEvent T8Expired(
    template(present) integer worker
  ) := TimerExpired(worker, ?, "t8", ?);
} with {
  encode "SimulatorInterface"; 
}
+0 −0

File added.

Preview size limit exceeded, changes collapsed.